Programmable payments hold USDC in smart contracts and release to a single recipient based on vesting schedules (paymentType vesting), time locks (paymentType time_lock), or threshold-based sweeps. Separate from share payouts which split revenue immediately at settlement. Delayed gratification, but on-chain and auditable.
Need machine-readable request/response bodies for your AI or codebase? Download this page as plain Markdown.
You lock 12,000 USDC via POST /programmable-payments/vestings/prepare with a 90-day cliff and 12 monthly periods. After the owner signs activation, automaticRelease releases each tranche on schedule and emits programmable-payment.vesting.released.
Dashboard → Payments → Programmable payments
Create vesting or time-lock payments from the dashboard forms: same fields as prepare endpoints. View payment status, toggle automaticRelease, trigger manual release, and manage threshold rules. Activation opens the owner wallet signing flow matching POST activate/relay.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
payerAddress | address | Yes | Wallet that locks funds (typically merchant owner or treasury hot wallet). |
recipientAddress | address | Yes | Wallet that claims vested tranches. |
asset | string | Yes | Asset symbol (USDC). |
amount | decimal string | Yes | Total locked amount in human units (e.g. "12000" for 12,000 USDC). |
cliffDelaySeconds | integer | Yes | Seconds after activation before any vesting unlocks. |
durationSeconds | integer | Yes | Total vesting duration in seconds from activation. |
periods | integer | Yes | Number of equal vesting periods after the cliff. |
automaticRelease | boolean | No | When true, due tranches are released automatically by background jobs. |
paymentId | uuid | No | Optional custom payment UUID. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
/programmable-payments/vestings/preparePrepare a vesting payment (paymentType vesting). Emits programmable-payment.vesting.prepared.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "businessId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",03 "chain": "base",04 "payerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",05 "recipientAddress": "0xContractor12345678901234567890123456789012",06 "asset": "USDC",07 "amount": "12000",08 "cliffDelaySeconds": 7776000,09 "durationSeconds": 31536000,10 "periods": 12,11 "automaticRelease": true12}| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
payerAddress | address | Yes | Wallet that locks funds until releaseAt. |
recipientAddress | address | Yes | Wallet that receives funds on release. |
asset | string | Yes | Asset symbol (USDC). |
amount | decimal string | Yes | Locked amount in human units. |
releaseAt | datetime | Yes | ISO-8601 datetime when funds become releasable. |
automaticRelease | boolean | No | When true, funds release automatically at releaseAt without a manual POST /release. |
paymentId | uuid | No | Optional custom payment UUID. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
/programmable-payments/time-locks/preparePrepare a time-lock payment (paymentType time_lock). Emits programmable-payment.timelock.prepared.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "businessId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",03 "chain": "base",04 "payerAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",05 "recipientAddress": "0xTreasuryCold123456789012345678901234567890",06 "asset": "USDC",07 "amount": "50000",08 "releaseAt": "2027-01-01T00:00:00.000Z",09 "automaticRelease": true10}| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
activationSignature / activationDeadline / activationNonce | string | No | From activationIntent typed data after payer signs. |
permitSignature / permitDeadline | string | No | Required when token permit is needed instead of approve tx. |
automaticRelease | boolean | No | Enable or disable automatic release/trigger cron. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
/programmable-payments/:pp_1a2b3c4d-5e6f-7890-abcd-ef123456789/activationGet activation intent and typed data for a prepared payment.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/programmable-payments/:pp_1a2b3c4d-5e6f-7890-abcd-ef123456789/activate/relaySubmit payer activation signature (and optional permit). Emits *.created webhook on confirmation.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "businessId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",03 "chain": "base",04 "activationSignature": "0x...",05 "activationDeadline": "1740000000",06 "activationNonce": "0",07 "permitSignature": "0x...",08 "permitDeadline": "1740000000"09}/programmable-payments/:pp_1a2b3c4d-5e6f-7890-abcd-ef123456789/syncReconcile payment state from an on-chain txHash.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "txHash": "0xabc123def4567890123456789012345678901234567890123456789012345678"03}/programmable-payments/:pp_1a2b3c4d-5e6f-7890-abcd-ef123456789/releaseManually release the next vested tranche or full time-lock amount when due. Emits *.released.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "authorization": {03 "pin": "1234"04 }05}/programmable-payments/:pp_1a2b3c4d-5e6f-7890-abcd-ef123456789/automationToggle automaticRelease for background release jobs.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "automaticRelease": false03}/programmable-payments/:pp_1a2b3c4d-5e6f-7890-abcd-ef123456789/cancelCancel unreleased vesting balance (vesting payments only). Emits programmable-payment.vesting.cancelled.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{}/programmable-payments/:pp_1a2b3c4d-5e6f-7890-abcd-ef123456789Retrieve payment status, released amounts, and schedule metadata.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/programmable-payments?paymentType=vesting&status=activeList programmable payments with filters.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/jsonMonitor a source wallet balance and sweep USDC to a recipient when balance exceeds thresholdAmount. Use automaticTrigger for hands-off treasury hygiene.
| Field | Type | Required | Description |
|---|---|---|---|
businessId | uuid | No | Target business. Omit when your API key is scoped to one business. |
chain | string | No | Chain scope for settlement APIs (base, polygon, etc.). Required for wallet direct/intent prepare. Sandbox resolves to testnets automatically. |
sourceWalletAddress | address | Yes | Hot wallet monitored for balance threshold. |
recipientAddress | address | Yes | Cold storage or treasury wallet receiving swept funds. |
asset | string | Yes | Asset symbol to monitor and sweep (USDC). |
thresholdAmount | decimal string | Yes | Balance above which a sweep is eligible. |
sweepAmount | decimal string | Yes | Amount to transfer when triggered. |
automaticTrigger | boolean | No | When true, background jobs trigger sweeps when balance exceeds threshold. |
ruleId | uuid | No | Optional custom rule UUID. |
authorization | object | No | Dashboard only. Step-up confirmation (PIN, OTP, or 2FA) when a logged-in owner acts in the browser. Omit entirely for secret API key integrations: the server skips this check when you authenticate with x-api-key. On sandbox, any emailed OTP code is `000000` (six zeroes). It's giving dev mode. Live sends a real code. |
authorization.pin | string | No | Transaction PIN when enabled. |
authorization.otpChallengeId | uuid | No | OTP challenge from a prior dashboard auth step. On sandbox, enter `000000` when verifying the emailed code. |
authorization.twoFactorCode | string | No | TOTP code when 2FA is enabled. |
/programmable-payments/threshold-rulesCreate a threshold sweep rule. Emits programmable-payment.threshold.created.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "businessId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",03 "chain": "base",04 "sourceWalletAddress": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",05 "recipientAddress": "0xColdStorage1234567890123456789012345678901",06 "asset": "USDC",07 "thresholdAmount": "100000",08 "sweepAmount": "50000",09 "automaticTrigger": true10}/programmable-payments/threshold-rules?limit=20List threshold rules with optional status and wallet filters.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/programmable-payments/threshold-rules/ptr_3c4d5e6f-7890-abcd-ef12-345678901234Retrieve a threshold rule.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json/programmable-payments/threshold-rules/ptr_3c4d5e6f-7890-abcd-ef12-345678901234/triggerManually trigger a sweep when balance exceeds threshold. Emits programmable-payment.threshold.triggered.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "authorization": {03 "pin": "1234"04 }05}/programmable-payments/threshold-rules/ptr_3c4d5e6f-7890-abcd-ef12-345678901234/automationToggle automaticTrigger for background monitoring.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{02 "automaticTrigger": true03}/programmable-payments/threshold-rules/ptr_3c4d5e6f-7890-abcd-ef12-345678901234/deactivateDeactivate a threshold rule. Emits programmable-payment.threshold.deactivated.
01x-api-key: sk_AbCdEfGhIj_XyZ1234567890abcdefghijklmnopqrstuvwxyz01234502Content-Type: application/json01{}| Field | Type | Required | Description |
|---|---|---|---|
paymentType | enum | No | vesting or time_lock: set by prepare endpoint, echoed in responses and webhooks. |
automaticRelease | boolean | No | Cron releases due vesting tranches or time-lock funds at releaseAt. |
cliffDelaySeconds | integer | No | Vesting only, seconds before first unlock. |
durationSeconds / periods | integer | No | Vesting only, total duration and number of equal unlock periods. |
releaseAt | datetime | No | Time-lock only, ISO datetime when funds unlock. |
Register a webhook endpoint and verify the X-Protocol-Signature header on every delivery before fulfilling orders or updating your database.
programmable-payment.vesting.preparedSent when vesting prepare completes and awaits activation.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: programmable-payment.vesting.prepared04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...programmable-payment.vesting.createdSent when vesting funds are locked on-chain after activation.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: programmable-payment.vesting.created04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...programmable-payment.vesting.releasedSent when a vesting tranche is released to the recipient.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: programmable-payment.vesting.released04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...programmable-payment.vesting.cancelledSent when unreleased vesting balance is cancelled.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: programmable-payment.vesting.cancelled04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...programmable-payment.timelock.preparedSent when time-lock prepare completes.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: programmable-payment.timelock.prepared04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...programmable-payment.timelock.createdSent when time-lock funds are locked on-chain.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: programmable-payment.timelock.created04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...programmable-payment.timelock.releasedSent when time-lock funds release to the recipient.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: programmable-payment.timelock.released04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...programmable-payment.threshold.createdSent when a threshold sweep rule is created.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: programmable-payment.threshold.created04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...programmable-payment.threshold.triggeredSent when a threshold sweep executes on-chain.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: programmable-payment.threshold.triggered04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...programmable-payment.threshold.deactivatedSent when a threshold rule is deactivated.
01Content-Type: application/json02User-Agent: Protocol-Webhooks/1.003X-Protocol-Event: programmable-payment.threshold.deactivated04X-Protocol-Delivery: wev_1a2b3c4d-5e6f-7890-abcd-ef123456789005X-Protocol-Business-Id: a1b2c3d4-e5f6-7890-abcd-ef123456789006X-Protocol-Attempt: 107X-Protocol-Signature: sha256=abc123def456...