Stripe MPP — Machine Payment Protocol
Syndicate Links implements Stripe's Machine Payment Protocol (MPP) — a standard for AI agent-native payments and affiliate multi-party payouts. This page covers the three endpoints your integration will use.
Overview
MPP lets AI agents discover your payment plans, initiate checkouts, and split revenue to affiliates automatically via Stripe's multi-party payout infrastructure. The flow is:
- Agent discovers plans at
/.well-known/machine-payments - Agent fetches the plan catalog at
GET /mpp/plans - Agent drives checkout at
POST /mpp/checkout - Stripe handles the split — your commission is credited to the affiliate's connected account
All MPP endpoints require a bearer token obtained from your Syndicate Links API key.
Authentication
Authorization: Bearer sl_live_...
Use an API key with the mpp:read scope for plan discovery and mpp:write for checkout. Keys are managed in your Merchant Dashboard under Settings → API Keys.
Endpoints
GET /mpp/plans
Returns the available payment plan catalog for your Syndicate Links merchant account. Agents use this to understand pricing options before initiating a checkout.
Request
GET /mpp/plans HTTP/1.1
Host: api.syndicatelinks.co
Authorization: Bearer sl_live_...
Accept: application/json
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
currency | string | No | ISO 4217 currency code. Defaults to usd. |
interval | string | No | Filter by billing interval: month, year, or one_time. |
Response 200 OK
{
"object": "list",
"data": [
{
"id": "plan_starter_monthly",
"object": "mpp_plan",
"name": "Starter",
"description": "Up to 1,000 tracked links per month",
"amount": 2900,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"stripe_price_id": "price_1OaB2cKZ6eF7gH8iJ9kL0mN",
"features": [
"1,000 tracked links",
"Basic analytics",
"API access",
"Email support"
],
"metadata": {
"tier": "starter"
}
},
{
"id": "plan_growth_monthly",
"object": "mpp_plan",
"name": "Growth",
"description": "Up to 25,000 tracked links per month",
"amount": 9900,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"stripe_price_id": "price_1OaB3cKZ6eF7gH8iJ9kL1mN",
"features": [
"25,000 tracked links",
"Advanced analytics",
"API access",
"Priority support",
"Custom domains"
],
"metadata": {
"tier": "growth"
}
}
],
"has_more": false
}
Field Reference
| Field | Type | Description |
|---|---|---|
id | string | Stable plan identifier for use in checkout requests |
amount | integer | Price in the smallest currency unit (cents for USD) |
currency | string | ISO 4217 currency code |
interval | string | Billing interval: month, year, or one_time |
stripe_price_id | string | Underlying Stripe Price ID |
features | array | Human-readable feature list for display |
POST /mpp/checkout
Initiates a Stripe Checkout Session for a given plan. The session includes affiliate attribution so commission is automatically split via Stripe's multi-party payout on conversion.
Request
POST /mpp/checkout HTTP/1.1
Host: api.syndicatelinks.co
Authorization: Bearer sl_live_...
Content-Type: application/json
Request Body
{
"plan_id": "plan_growth_monthly",
"affiliate_token": "aff_tok_abc123xyz",
"success_url": "https://yourapp.com/welcome?session_id={CHECKOUT_SESSION_ID}",
"cancel_url": "https://yourapp.com/pricing",
"customer_email": "user@example.com",
"metadata": {
"agent_session_id": "agt_sess_789",
"source": "chatgpt_plugin"
}
}
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
plan_id | string | Yes | Plan ID from /mpp/plans |
affiliate_token | string | Yes | Signed affiliate attribution token (see ACP Attribution) |
success_url | string | Yes | Redirect URL after successful payment. Use {CHECKOUT_SESSION_ID} placeholder. |
cancel_url | string | Yes | Redirect URL on cancellation |
customer_email | string | No | Pre-fill the customer email in Checkout |
metadata | object | No | Arbitrary key-value pairs attached to the Stripe session |
Response 201 Created
{
"object": "mpp_checkout_session",
"id": "cs_live_a1B2c3D4e5F6g7H8i9J0",
"url": "https://checkout.stripe.com/c/pay/cs_live_a1B2c3D4...",
"plan_id": "plan_growth_monthly",
"affiliate_token": "aff_tok_abc123xyz",
"expires_at": 1711670400,
"status": "open"
}
Field Reference
| Field | Type | Description |
|---|---|---|
id | string | Stripe Checkout Session ID |
url | string | Redirect the user or agent to this URL to complete payment |
expires_at | integer | Unix timestamp when this session expires (default: 24 hours) |
status | string | open, complete, or expired |
Commission Split
When the checkout completes, Syndicate Links automatically creates a Stripe Transfer to the affiliate's connected account. The split percentage is defined by the affiliate program's commission rate. Your Stripe Connect dashboard will show the transfer under Connect → Transfers.
GET /.well-known/machine-payments
The MPP discovery endpoint. AI agents and payment-aware clients fetch this URL to determine whether a host supports MPP and where to find the plan catalog and checkout endpoint.
This endpoint is served from your custom domain if configured, or from the Syndicate Links proxy domain for your merchant account.
Request
GET /.well-known/machine-payments HTTP/1.1
Host: payments.yourapp.com
Accept: application/json
No authentication required — this is a public discovery document.
Response 200 OK
{
"version": "1.0",
"vendor": "syndicate-links",
"plans_url": "https://api.syndicatelinks.co/mpp/plans",
"checkout_url": "https://api.syndicatelinks.co/mpp/checkout",
"currency": "usd",
"supported_intervals": ["month", "year"],
"attribution": {
"acp_version": "2.3",
"token_endpoint": "https://api.syndicatelinks.co/v1/attribution/token"
},
"contact": "payments@yourapp.com"
}
Field Reference
| Field | Type | Description |
|---|---|---|
version | string | MPP spec version |
plans_url | string | Absolute URL to the plans catalog endpoint |
checkout_url | string | Absolute URL to initiate checkout |
attribution.acp_version | string | ACP Attribution spec version in use |
attribution.token_endpoint | string | URL to obtain signed affiliate attribution tokens |
Custom Domain Setup
To serve /.well-known/machine-payments from your own domain, add a CNAME in your DNS:
payments.yourapp.com CNAME proxy.syndicatelinks.co
Then configure the domain in your Merchant Dashboard under Settings → Custom Domains.
Webhooks
Subscribe to these Stripe events to track MPP payment lifecycle:
| Event | Description |
|---|---|
checkout.session.completed | Payment succeeded; commission split initiated |
checkout.session.expired | Session expired without payment |
transfer.created | Affiliate commission transfer created in Stripe Connect |
transfer.failed | Commission transfer failed; see failure_code |
Webhook configuration is in your Merchant Dashboard under Settings → Webhooks.
Error Codes
| HTTP Status | Code | Description |
|---|---|---|
400 | invalid_plan | The plan_id does not exist or is inactive |
400 | invalid_affiliate_token | The affiliate_token is malformed or expired |
401 | unauthorized | Missing or invalid bearer token |
403 | insufficient_scope | Token lacks required scope (mpp:write) |
422 | checkout_failed | Stripe returned an error creating the session |
429 | rate_limited | Too many requests; see Retry-After header |
Error Response Format
{
"error": {
"code": "invalid_affiliate_token",
"message": "The affiliate token has expired. Request a new token from /v1/attribution/token.",
"request_id": "req_abc123"
}
}
Quick Start
// 1. Fetch available plans
const plans = await fetch('https://api.syndicatelinks.co/mpp/plans', {
headers: { Authorization: `Bearer ${apiKey}` },
}).then(r => r.json())
// 2. Get an affiliate attribution token
const tokenRes = await fetch('https://api.syndicatelinks.co/v1/attribution/token', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ affiliate_id: 'aff_abc123', link_id: 'lnk_xyz789' }),
}).then(r => r.json())
// 3. Create a checkout session
const session = await fetch('https://api.syndicatelinks.co/mpp/checkout', {
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
plan_id: plans.data[0].id,
affiliate_token: tokenRes.token,
success_url: 'https://yourapp.com/welcome?session_id={CHECKOUT_SESSION_ID}',
cancel_url: 'https://yourapp.com/pricing',
}),
}).then(r => r.json())
// 4. Redirect user to Stripe Checkout
window.location.href = session.url