Payment Intents
Create and submit payment intents for agentic payments
Overview
The Payment Intents allow you to create payment intents that define spending parameters and budgets for agentic payments. Intents specify the purpose, amount, time period, and spending limits for automated payment processing. Once created, payment intents go through an approval process before becoming active.
Authorization: Bearer {access_token} header and the x-appid: {clientId} header in your requests.
Create Payment Intent
Creates a new payment intent for a specific intent type. The AllocatableType ID determines what kind of payment intent you're creating (e.g., Travel, IT, Meals, etc.). This intent defines the spending parameters for agentic payment processing.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | The unique identifier of the AllocatableType (intent type) you want to create a payment intent for |
Request Body
The request body must contain the following required fields and can include optional fields for additional configuration.
| Parameter | Type | Required | Description |
|---|---|---|---|
amount |
number | Yes | The budget amount allocated for this payment intent |
start |
string (date) | Yes | The start date when the payment intent becomes active in YYYY-MM-DD format (UTC) |
end |
string (date) | Yes | The end date when the payment intent expires in YYYY-MM-DD format (UTC) |
ownerId |
string | Yes | The ID of the user who will own this payment intent |
budgetCategoryType |
string | No | The expense category type. If not provided and only one option is available, it will be used automatically. Must match available categories for the intent type. |
currency |
string | No | The currency code (e.g., "USD", "EUR", "ILS"). Defaults to the user's default currency if not provided. |
name |
string | No | A custom name for the payment intent. If not provided, a name will be auto-generated based on the intent type and amount. |
purpose |
string | No | A description or purpose for the payment intent |
costCenterIds |
array | No | Array of cost center IDs to associate with this payment intent |
purchaseOrder |
string | No | Purchase order number associated with this payment intent |
boundToCardId |
string | No | ID of a specific card to bind this payment intent to |
dailyLimit |
number | No | Maximum amount that can be spent per day |
txLimit |
number | No | Maximum amount per transaction |
weekDaysLimit |
string | No | A 7-character string representing which days of the week are enabled. Each character is either 0 (disabled) or 1 (enabled). Position 0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday. Example: "1111100" enables Monday-Friday only, "1111111" enables all days. |
hoursLimit |
string | No | A 24-character string representing which hours of the day are enabled. Each character is either 0 (disabled) or 1 (enabled). Position 0 = 12:00 AM (midnight), 1 = 1:00 AM, ..., 23 = 11:00 PM. Example: "000000000000111111110000" enables 12:00 PM - 10:00 PM only (business hours), "111111111111111111111111" enables all hours. |
txCountLimit |
number | No | Maximum number of transactions allowed |
txDailyCountLimit |
number | No | Maximum number of transactions per day |
forceBudgetId |
string | No | Force the payment intent to use a specific budget ID |
forceCostCenterIds |
array or string | No | Force specific cost center IDs (overrides costCenterIds) |
forceGlAccountCode |
string | No | Force a specific GL account code |
forceMultiple |
boolean or string | No | Allow multiple payment intents with the same parameters (default: false) |
partialAuth |
boolean | No | Whether partial authorization is allowed for payments |
expenseIds |
array | No | Array of expense IDs to associate with this payment intent |
private |
boolean | No | Whether the payment intent is private (not visible to all users) |
Example Request
Using cURL:
curl -X POST https://sandbox.custodia-tech.com/md/api/AllocatableTypes/550e8400-e29b-41d4-a716-446655440000/createActivity \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID" \
-H "Content-Type: application/json" \
-d '{
"amount": 1000,
"start": "2024-01-15",
"end": "2024-01-25",
"ownerId": "user-id-123",
"currency": "USD",
"purpose": "Business trip to New York",
"name": "NYC Business Trip"
}'
Using JavaScript (fetch):
const allocatableTypeId = '550e8400-e29b-41d4-a716-446655440000';
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/AllocatableTypes/${allocatableTypeId}/createActivity`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 1000,
start: '2024-01-15',
end: '2024-01-25',
ownerId: 'user-id-123',
currency: 'USD',
purpose: 'Business trip to New York',
name: 'NYC Business Trip'
})
});
const paymentIntent = await response.json();
Creating a payment intent with spending limits:
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/AllocatableTypes/${allocatableTypeId}/createActivity`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId,
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 5000,
start: '2024-02-01',
end: '2024-02-28',
ownerId: 'user-id-123',
currency: 'USD',
purpose: 'Monthly IT equipment budget',
dailyLimit: 500,
txLimit: 200,
weekDaysLimit: '1111100', // Monday-Friday only
hoursLimit: '000000000000111111110000', // 12:00 PM - 10:00 PM only
txCountLimit: 50
})
});
Response
Success Response (200 OK)
{
"id": "request-id-123",
"associatedId": "allocation-id-456",
"status": "pending",
"amount": 1000,
"currency": "USD",
"ownerId": "user-id-123",
"name": "NYC Business Trip",
"purpose": "Business trip to New York",
"start": "2024-01-15",
"end": "2024-01-25",
"created": "2024-01-10T10:00:00.000Z"
}
Get Payment Intents (Allocations)
Retrieves a list of payment intents (allocations) that are currently available. You can filter, sort, and paginate the results using query parameters.
Query Parameters
Use the filter query parameter to filter, sort, and paginate results. The filter should be a JSON object passed as a URL-encoded string.
| Parameter | Type | Description |
|---|---|---|
filter |
object (JSON) | Filter, sorting, and pagination options. See filter options below. |
Filter Options
The filter object supports the following properties:
| Property | Type | Description |
|---|---|---|
where |
object | Filter conditions. See where clause examples below. |
fields |
array | Array of field names to include in the response |
order |
string | Sort order (e.g., "activationDate DESC" or "title ASC") |
limit |
number | Maximum number of results to return |
skip |
number | Number of results to skip (for pagination) |
include |
array | Related models to include (e.g., ["allocatedTo", "budgetAllocations"]) |
utilization |
boolean | Include utilization metrics (used, pending, remaining amounts) |
Where Clause Examples
Common filter conditions for the where clause:
| Field | Example | Description |
|---|---|---|
ownerId |
{"ownerId": "user-id-123"} |
Filter by user who owns the payment intent |
companyId |
{"companyId": "company-id-123"} |
Filter by company ID |
status |
{"status": "active"} |
Filter by status: "new", "active", "expired", "ended", "used", "archived", "locked" |
status (multiple) |
{"status": {"inq": ["active", "new"]}} |
Filter by multiple status values |
activationDate |
{"activationDate": {"gte": "2024-01-01"}} |
Filter by activation date (greater than or equal) |
expirationDate |
{"expirationDate": {"lte": "2024-12-31"}} |
Filter by expiration date (less than or equal) |
title |
{"title": {"like": "%Business Trip%"}} |
Search by title (case-insensitive partial match) |
boundToCardId |
{"boundToCardId": "card-id-123"} |
Filter by card ID if intent is bound to a specific card |
Example Requests
Get all active payment intents for a user:
const filter = {
where: {
ownerId: 'user-id-123',
status: 'active'
},
utilization: true,
order: 'activationDate DESC'
};
const filterParam = encodeURIComponent(JSON.stringify(filter));
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/Allocations?filter=${filterParam}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId
}
});
const paymentIntents = await response.json();
Get active and new payment intents with utilization metrics:
const filter = {
where: {
ownerId: 'user-id-123',
status: {inq: ['active', 'new']}
},
utilization: true,
include: ['allocatedTo'],
order: 'expirationDate ASC',
limit: 50
};
const filterParam = encodeURIComponent(JSON.stringify(filter));
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/Allocations?filter=${filterParam}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId
}
});
const paymentIntents = await response.json();
Search payment intents by title or purpose:
const filter = {
where: {
ownerId: 'user-id-123',
or: [
{title: {like: '%Business Trip%'}},
{purpose: {like: '%Conference%'}}
]
},
utilization: true
};
const filterParam = encodeURIComponent(JSON.stringify(filter));
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/Allocations?filter=${filterParam}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId
}
});
const paymentIntents = await response.json();
Response
Success Response (200 OK)
[
{
"id": "allocation-id-123",
"title": "NYC Business Trip",
"purpose": "Business trip to New York",
"status": "active",
"ownerId": "user-id-123",
"companyId": "company-id-123",
"amount": 1000,
"currency": "USD",
"used": 250,
"pending": 50,
"amountLeft": 700,
"activationDate": "2024-01-15T00:00:00.000Z",
"expirationDate": "2024-01-25T00:00:00.000Z",
"activityStart": "2024-01-15",
"activityEnd": "2024-01-25",
"boundToCardId": null,
"allocatedToType": "Travel",
"created": "2024-01-10T10:00:00.000Z",
"modified": "2024-01-15T00:00:00.000Z"
},
{
"id": "allocation-id-456",
"title": "Monthly IT Budget",
"purpose": "IT equipment and software",
"status": "active",
"ownerId": "user-id-123",
"companyId": "company-id-123",
"amount": 5000,
"currency": "USD",
"used": 1200,
"pending": 300,
"amountLeft": 3500,
"activationDate": "2024-02-01T00:00:00.000Z",
"expirationDate": "2024-02-28T23:59:59.000Z",
"activityStart": "2024-02-01",
"activityEnd": "2024-02-28",
"boundToCardId": "card-id-789",
"allocatedToType": "IT",
"created": "2024-01-25T10:00:00.000Z",
"modified": "2024-02-01T00:00:00.000Z"
}
]
Get Payment Intent by ID
Retrieves detailed information about a specific payment intent (allocation) by its ID.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
allocationId |
string | Yes | The unique identifier of the payment intent (allocation) |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
filter |
object (JSON) | Optional filter to specify which fields to include or related models (e.g., {"fields": ["id", "title", "status", "amount"], "utilization": true}) |
Example Request
Using cURL:
curl -X GET "https://sandbox.custodia-tech.com/md/api/Allocations/allocation-id-123?filter=%7B%22utilization%22%3Atrue%7D" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "x-appid: YOUR_CLIENT_ID"
Using JavaScript (fetch):
const allocationId = 'allocation-id-123';
const filter = {
utilization: true,
include: ['allocatedTo', 'budgetAllocations']
};
const filterParam = encodeURIComponent(JSON.stringify(filter));
const response = await fetch(`https://sandbox.custodia-tech.com/md/api/Allocations/${allocationId}?filter=${filterParam}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${accessToken}`,
'x-appid': clientId
}
});
const paymentIntent = await response.json();
Response
Success Response (200 OK)
{
"id": "allocation-id-123",
"title": "NYC Business Trip",
"description": null,
"purpose": "Business trip to New York",
"status": "active",
"ownerId": "user-id-123",
"companyId": "company-id-123",
"amount": 1000,
"currency": "USD",
"used": 250,
"pending": 50,
"amountLeft": 700,
"activationDate": "2024-01-15T00:00:00.000Z",
"expirationDate": "2024-01-25T00:00:00.000Z",
"activityStart": "2024-01-15",
"activityEnd": "2024-01-25",
"boundToCardId": null,
"allocatedToType": "Travel",
"allocatedToId": "allocatable-type-id",
"dailyLimit": null,
"txLimit": null,
"weekDaysLimit": "1111111",
"hoursLimit": "111111111111111111111111",
"txCountLimit": null,
"merchants": [],
"keywords": [],
"created": "2024-01-10T10:00:00.000Z",
"modified": "2024-01-15T00:00:00.000Z"
}
Payment Intent Fields
The following fields are available in payment intent (allocation) responses:
| Field | Type | Description |
|---|---|---|
id |
string | Unique identifier for the payment intent |
title |
string | Title/name of the payment intent |
purpose |
string | Purpose or description of the payment intent |
status |
string | Status: "new", "active", "expired", "ended", "used", "archived", "locked" |
ownerId |
string | ID of the user who owns this payment intent |
companyId |
string | ID of the company this payment intent belongs to |
amount |
number | Total budget amount allocated |
currency |
string | Currency code (e.g., "USD", "EUR", "ILS") |
used |
number | Amount already used (included when utilization: true) |
pending |
number | Amount pending in transactions (included when utilization: true) |
amountLeft |
number | Remaining available amount (included when utilization: true) |
activationDate |
date | Date when the payment intent becomes active |
expirationDate |
date | Date when the payment intent expires |
activityStart |
string | Start date in YYYY-MM-DD format |
activityEnd |
string | End date in YYYY-MM-DD format |
boundToCardId |
string | ID of card this intent is bound to (null if not bound to a specific card) |
allocatedToType |
string | Type of activity/intent (e.g., "Travel", "IT", "Meals") |
dailyLimit |
number | Maximum amount per day (if set) |
txLimit |
number | Maximum amount per transaction (if set) |
weekDaysLimit |
string | A 7-character string representing which days of the week are enabled. Each character is either 0 (disabled) or 1 (enabled). Position 0 = Sunday, 1 = Monday, 2 = Tuesday, 3 = Wednesday, 4 = Thursday, 5 = Friday, 6 = Saturday. Example: "1111100" enables Monday-Friday only, "1111111" enables all days. |
merchants |
array | List of allowed merchants (if restricted) |
keywords |
array | Keywords/tags associated with the payment intent |
utilization: true in your filter to get real-time spending metrics (used, pending, amountLeft) for each payment intent. This is especially useful for agentic payment processing to check available budget before making payments.
Error Responses
All endpoints may return the following error responses:
| Status Code | Description | Solution |
|---|---|---|
401 Unauthorized |
Invalid or missing access token | Verify your access token is valid and included in the Authorization header |
400 Bad Request |
Invalid request parameters or missing required fields | Check that all required fields (amount, start, end, ownerId) are included and have valid values |
404 Not Found |
AllocatableType or Allocation not found | Verify the ID is correct and exists for your company |
400 Bad Request |
Invalid budgetCategoryType | Ensure the budgetCategoryType matches one of the available categories for the intent type |
400 Bad Request |
Currency must be set | Provide a currency code or ensure the user has a default currency configured |
403 Forbidden |
Insufficient permissions | Verify your access token has the required scopes and permissions |