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.

Note: All endpoints require proper authentication. Make sure to include the Authorization: Bearer {access_token} header and the x-appid: {clientId} header in your requests.

Create Payment Intent

POST /md/api/AllocatableTypes/{id}/createActivity

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"
}
Note: The response includes both a request ID and an associated allocation ID. The payment intent goes through an approval process. Once approved, the intent becomes active and can be used for agentic payment processing.

Get Payment Intents (Allocations)

GET /md/api/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

GET /md/api/Allocations/{allocationId}

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
Tip: Use 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
Important: Payment intents are subject to approval workflows. The intent will not be active until it has been approved. Check the request status to see if it has been approved or if additional information is needed. Once active, the payment intent can be used for agentic payment processing within the specified parameters.