Prerequisites

  • Read the Quick Start Guide.
  • Obtain a card product token and a token for an active card that is associated with that card product.

Concepts

Levels of control

The Marqeta platform enables you to create controls that apply to an individual user or to a set of users associated with a specific card product. Marqeta may create additional program-level controls, which apply to all users. Multiple controls can be applied at each level to control how, when, and where your users spend with their cards.

To define the level to which your control applies, your API request must include an association object. The association object requires one of the following:

  • Card product token – The card product to which the control applies.
  • User token – The user to which the control applies.

Note: Program-level controls have an empty association object. While you can create controls of this type in the sandbox, only Marqeta can create and update program-level controls in production. You can retrieve program-level controls in production and in the sandbox.

Program-level controls

Program-level controls are global and apply to every card product and user in your environment. These controls cannot be created using the production API. You will work with Marqeta to define program-level controls for your program, often based on the requirements of the issuing bank. The controls you create must operate within the bounds of the controls created by Marqeta.

Marqeta also helps you define other program-specific configurations based on technical and bank requirements specific to your implementation. To review configurations for your program, contact your Marqeta Customer Success representative.

Card product-level controls

Card product-level controls apply to a collection of cards sharing the same properties. They apply to all users with cards associated with that card product. To define a control at the card product level, include a card product token in the association object.

Marqeta also helps you define other card product-specific configurations based on technical and bank requirements specific to your implementation.

Note: Controls cannot be applied to individual cards.

User-level controls

User-level controls apply to a single user—the card holder. To define a control at the user level, include a user token in the association object.

Controls to limit where users can spend

To limit where users can spend funds, use authorization controls. Authorization controls allow you to pick the merchants where users can (or cannot) spend their funds.

In the API request, the merchant_scope object defines the merchant or group of merchants affected by the authorization control. The object requires one (and only one) of the following identifiers:

  • Merchant ID – A unique identifier for a single merchant.
  • Merchant Category Code (MCC) – A unique identifier for a type of goods or services provided by a set of merchants.
  • MCC Group – A unique identifier for a group of merchant category codes.

Your program's default authorization behavior can block all merchants by default, requiring you to whitelist allowable merchants, or it can allow all merchants by default, requiring you to blacklist blocked merchants. Make sure you know your program's default behavior before designing your controls. There is no distinction between a control that allows or blocks merchants—it is an exception to your program's default behavior. For example, a control that includes the MCC for hotels (7011) in the merchant_scope object would block hotels under the blacklist default behavior, but would allow hotels under the whitelist default behavior.

You can optionally configure start and end dates for your control to limit spending at merchants for predetermined periods of time. For example, a rewards card might limit a user's ability to spend outside of specific promotional periods.

Controls to limit amount and frequency of spending

To limit the amount or frequency of spending, use velocity controls. Velocity controls allow you to set how much users can spend and/or the number of transactions they can make within a given window of time.

The configurable parameters for velocity controls include:

  • Amount limit – The maximum amount the user can spend in a given window of time (such as $200 per day, $1000 per month).
  • Usage limit – The maximum number of transactions the user can make in a given window of time (such as three transactions per day, ten transactions per month).
  • Velocity window – The window of time over which the control applies (such as per day, per week, per month, forever, per transaction).
  • Transaction types – The type of transactions to which the control applies (such as retail purchases, ATM withdrawals, bank transfers).
  • Merchant scope The merchant or group of merchants to which the control applies (such as MID 12345).

Authorization controls vs. velocity controls

Authorization and velocity controls share some attributes and behaviors, but they serve distinct purposes.

  • Authorization controls block (or allow) transactions at one or more merchants, regardless of the amount or frequency of spending. For example, you can block your users from spending at a grocery store for all time or block them for a specific period of time, but you can't limit the spending amount within that time period using an authorization control.
  • Velocity controls limit transactions at one or more merchants based on a velocity window. For example, you can limit spending at grocery stores to a maximum of $100 each week.

Controls at transaction time

When a user attempts to spend with a card, the Marqeta platform evaluates the transaction against all controls applied to that user, including controls applied at the program and card product levels. If the details of the transaction violate any of the controls, the transaction fails.

The following transactions do not apply to the limits defined in a velocity control:

  • Declined authorizations
  • Account verification authorizations

The effects of all velocity controls are user-specific. If a card product has a velocity control limiting users to $100 of spending each day, then each associated user can spend $100. They are not impacted by the spending of other users, even if they share a parent account.

If a user owns multiple cards, spend controls apply in the following ways:

  • If a user has multiple cards associated with the same card product, then spending on any of those cards counts toward any velocity controls applied to that card product. In other words, all of the user’s cards share the card product's velocity control.
  • If a user has multiple cards associated with different card products, then spending on a card only counts toward velocity controls applied to its card product. In other words, spending on a card associated with Card Product A does not affect the limits of a card associated with Card Product B. 
  • A velocity control applied to a user always affects all of the user's cards.

For more information about how many cards a user can own, see About Cards.

Note: When using a card funded using Just-in-Time (JIT) Funding, every spend event has a matching load event that returns the account balance to zero. Load controls operate similarly to spend controls—they limit the amount and frequency of funds that can be added to an account. To understand the load controls applied to your program, contact your Marqeta Customer Success representative. To learn more about JIT Funding, see About Just-in-Time Funding.


Tutorial

The following tutorial walks you through creating and testing a control in the shared sandbox. You will create an authorization control that prevents users of your new card product from spending at liquor stores, which are represented by a single merchant category code.

If you want to test these controls after you create them, make sure to track the user and card product tokens you specify throughout the tutorial.

Step One: List existing controls

Before creating a new control, consider any existing controls you may have at the program and card product levels. To view existing authorization controls, send a request to the GET /authcontrols endpoint.

Make sure you understand your program's default authorization behavior (allow vs. deny). In the shared sandbox, the program's default behavior is set to globally allow transactions at all merchants.

Step Two: Design your controls

The business logic of the control you want to add determines the data you include in your request.

  • To block spending at all liquor stores, include the merchant category code in the merchant_scope object.
  • To apply the control to all users in your card product, include the card product token in the association object.

To avoid receiving an error, include all other necessary parameters.

  • Create a meaningful name for the control: e.g. Deny Liquor Stores.
  • Create a unique token for the control: e.g. deny_liquor_stores.

Note: Do not use the example tokens shown in the tutorial while working in the shared sandbox. If an object with the same token already exists, the system will handle the request as a duplicate, and your request will not take effect.

Step Three: Call the /authcontrols endpoint

The following code block provides a JSON-formatted sample message body for creating your control. Copy the code sample and paste it into the body field of the following widget. Replace any placeholder text (**UNIQUE TOKEN**, **CARD PRODUCT TOKEN**) with your sample data, then click "Submit Request." Review the response to ensure you successfully created the authorization control.

{
"token": "**UNIQUE TOKEN**",
"name": "Deny Liquor Stores",
"association": {
"card_product_token": "**CARD PRODUCT TOKEN**"
},
"merchant_scope": {
"mcc": "5921"
},
"active": true
}

Alternatively, you can use the following sample cURL to create the same control.

curl \
-X POST \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic **YOUR AUTHORIZATION STRING**' \
-d '{
"token": "**UNIQUE TOKEN**",
"name": "Deny Liquor Stores",
"association": {
"card_product_token": "**CARD PRODUCT TOKEN**"
},
"merchant_scope": {
"mcc": "5921"
},
"active": true
}' \
'https://shared-sandbox-api.marqeta.com/v3/authcontrols'

Step Four: Confirm the new control exists

To confirm that you created the control, call the GET /authcontrols endpoint using the card product token you used previously. Replace any placeholder text (**CARD PRODUCT TOKEN**) with your sample data. Your new control should be included in the returned list.

https://shared-sandbox-api.marqeta.com/v3/authcontrols?card_product=**CARD PRODUCT TOKEN**&count=5&sort_by=-lastModifiedTime

Step Five: Call the /simulate endpoint

To test if the control functions properly, simulate an authorization transaction using the POST /simulate/authorization endpoint. Test several transactions that each force the Marqeta platform to allow or deny them.

The following sample message body creates a transaction that the Marqeta platform denies because of the authorization control created in the tutorial. Replace any placeholder text (**YOUR CARD TOKEN**) with your sample data. Change the MCC and resubmit the request to simulate a transaction that Marqeta allows.

{
"amount": "100",
"mid": "12345",
"card_token": "**YOUR CARD TOKEN**",
"card_acceptor": {
"mcc":"5921"
}
}

Note: When testing controls in the shared sandbox, keep in mind that controls created by other sandbox users might impact your testing. If the transaction result is unexpected, check the response body for details on what went wrong.


Samples

Use the following samples to help build your program's spend controls. Each sample includes a description of the use case and sample JSON and cURL code snippets.

Allow user spending at a single merchant

You can limit a user's spending to a single merchant. This is handy if you are creating a rewards card that should only be used at a specific retailer or service. (Depending on your program's default authorization behavior, the same control could be used to block spending at a single merchant.)

{
"token": "**UNIQUE TOKEN**",
"name": "Only Dunkin Donuts",
"association": {
"user_token": "**USER TOKEN REQUIRED**"
},
"merchant_scope": {
"mid": "252824676910001"
},
"active": true
}

curl \
-X POST \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic **YOUR AUTHORIZATION STRING**' \
-d '{
"token": "**UNIQUE TOKEN**",
"name": "Only Dunkin Donuts",
"association": {
"user_token": "**USER TOKEN REQUIRED**"
},
"merchant_scope": {
"mid": "252824676910001"
},
"active": true
}' \
'https://shared-sandbox-api.marqeta.com/v3/authcontrols'

Limit spending to $100 per day

Using a velocity control, you can cap the amount a user spends in a given timeframe. If, for example, you know your card holders shouldn't spend more than $100 per day, you could use a velocity control to deny any transactions beyond that limit.

{
"token": "**UNIQUE TOKEN**",
"name": "100 Daily Spend Limit",
"association": {
"user_token": "**USER TOKEN**"
},
"usage_limit": 100,
"currency_code": "USD",
"amount_limit": 100,
"velocity_window": "DAY",
"active": true
}

curl \
-X POST \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic **YOUR AUTHORIZATION STRING**' \
-d '{
"token": "**UNIQUE TOKEN**",
"name": "100 Daily Spend Limit",
"association": {
"user_token": "**USER TOKEN**"
},
"usage_limit": 100,
"currency_code": "USD",
"amount_limit": 100,
"velocity_window": "DAY",
"active": true
}' \
'https://shared-sandbox-api.marqeta.com/v3/velocitycontrols'

Limit spending to $100 per transaction

You can limit a user's per-transaction spending by creating a velocity control with the velocity_window field set to TRANSACTION.

{
"token": "**UNIQUE TOKEN**",
"name": "100 Per Transaction Limit",
"association": {
"user_token": "**USER TOKEN**"
},
"currency_code": "USD",
"amount_limit": 100,
"velocity_window": "TRANSACTION",
"active": true
}

curl \
-X POST \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic **YOUR AUTHORIZATION STRING**' \
-d '{
"token": "**UNIQUE TOKEN**",
"name": "100 Per Transaction Limit",
"association": {
"user_token": "**USER TOKEN**"
},
"currency_code": "USD",
"amount_limit": 100,
"velocity_window": "TRANSACTION",
"active": true
}' \
'https://shared-sandbox-api.marqeta.com/v3/velocitycontrols'

Limit users to one transaction per week at a category of merchants

You can limit a user's maximum number of transactions for a given time period. For example, you can create a limited-use card product that prevents users from spending too frequently at a given merchant or category of merchants, such as hotels and motels. This is handy if you know how frequently a card holder should be spending with their card.

{
"token": "**UNIQUE TOKEN**",
"name": "One Transaction Per Week at Hotels",
"association": {
"card_product_token": "**CARD PRODUCT TOKEN REQUIRED**"
},
"merchant_scope": {
"mcc": "7011"
},
"usage_limit": "1",
"currency_code": "USD",
"amount_limit": 1000,
"velocity_window": "WEEK",
"active": true
}

curl \
-X POST \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic **YOUR AUTHORIZATION STRING**' \
-d '{
"token": "**UNIQUE TOKEN**",
"name": "One Transaction Per Week At Hotels",
"association": {
"card_product_token": "**CARD PRODUCT TOKEN REQUIRED**"
},
"merchant_scope": { "mcc": "7011" },
"usage_limit": 1,
"currency_code": "USD",
"amount_limit": 1000,
"velocity_window": "WEEK",
"active": true
}' \
'https://shared-sandbox-api.marqeta.com/v3/velocitycontrols'

Limit users to a single purchase

You can add a velocity control that allows a user to spend exactly once. By setting the usage limit to one (a single transaction) and the velocity window to lifetime, users can spend up to the amount limit once. Any future attempts to spend are blocked.

{
"token": "**UNIQUE TOKEN**",
"name": "Single Use Card",
"association": {
"card_product_token": "**CARD PRODUCT TOKEN REQUIRED**"
},
"usage_limit": 1,
"currency_code": "USD",
"amount_limit": 1000,
"velocity_window": "LIFETIME",
"active": true
}

curl \
-X POST \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic **YOUR AUTHORIZATION STRING**' \
-d '{
"token": "**UNIQUE TOKEN**",    
"name": "Single Use Card",    
"association": {      
"card_product_token": "**CARD PRODUCT TOKEN**"    
},    
"usage_limit": 1,    
"currency_code": "USD",    
"amount_limit": 1000,    
"velocity_window": "LIFETIME",    
"active": true  
}' \
'https://shared-sandbox-api.marqeta.com/v3/velocitycontrols'

Limit ATM withdrawals and bank transfers

You can create a velocity control to limit the funds users can withdraw from ATMs or transfer from a bank. By setting the spending limit for ATMs and bank transfers to $0, the user can only make retail purchases.

{
"token": "**UNIQUE TOKEN**",
"name": "No ATMS or Bank Transfers",
"association": {
"user_token": "**USER TOKEN REQUIRED**"
},
"usage_limit": 100,
"approvals_only": true,
"include_purchases": false,
"include_withdrawals": true,
"include_transfers": true,
"currency_code": "USD",
"amount_limit": 0,
"velocity_window": "MONTH",
"active": true
}

curl \
-X POST \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Basic **YOUR AUTHORIZATION STRING**' \
-d '{
"token": "**UNIQUE TOKEN**",
"name": "No ATMS or Bank Transfers",
"association": {
"user_token": "**USER TOKEN**"
}, "usage_limit": 100,
"approvals_only": true,
"include_purchases": false,
"include_withdrawals": true,
"include_transfers": true,
"currency_code": "USD",
"amount_limit": 0,
"velocity_window": "MONTH",
"active": true
}' \
'https://shared-sandbox-api.marqeta.com/v3/velocitycontrols'

List all velocity controls for a single user

You can retrieve a list of all velocity controls applied at the program level, or use a query parameter to filter the list of controls by user or card product.

https://shared-sandbox-api.marqeta.com/v3/velocitycontrols?user=**USER TOKEN REQUIRED**

curl \
-X GET \
--header 'Accept: application/json' \
--header 'Authorization: Basic **YOUR AUTHORIZATION STRING**' \
'https://shared-sandbox-api.marqeta.com/v3/velocitycontrols?user=**USER TOKEN REQUIRED**'