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:

  1. Agent discovers plans at /.well-known/machine-payments
  2. Agent fetches the plan catalog at GET /mpp/plans
  3. Agent drives checkout at POST /mpp/checkout
  4. 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

ParameterTypeRequiredDescription
currencystringNoISO 4217 currency code. Defaults to usd.
intervalstringNoFilter 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

FieldTypeDescription
idstringStable plan identifier for use in checkout requests
amountintegerPrice in the smallest currency unit (cents for USD)
currencystringISO 4217 currency code
intervalstringBilling interval: month, year, or one_time
stripe_price_idstringUnderlying Stripe Price ID
featuresarrayHuman-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

ParameterTypeRequiredDescription
plan_idstringYesPlan ID from /mpp/plans
affiliate_tokenstringYesSigned affiliate attribution token (see ACP Attribution)
success_urlstringYesRedirect URL after successful payment. Use {CHECKOUT_SESSION_ID} placeholder.
cancel_urlstringYesRedirect URL on cancellation
customer_emailstringNoPre-fill the customer email in Checkout
metadataobjectNoArbitrary 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

FieldTypeDescription
idstringStripe Checkout Session ID
urlstringRedirect the user or agent to this URL to complete payment
expires_atintegerUnix timestamp when this session expires (default: 24 hours)
statusstringopen, 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

FieldTypeDescription
versionstringMPP spec version
plans_urlstringAbsolute URL to the plans catalog endpoint
checkout_urlstringAbsolute URL to initiate checkout
attribution.acp_versionstringACP Attribution spec version in use
attribution.token_endpointstringURL 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:

EventDescription
checkout.session.completedPayment succeeded; commission split initiated
checkout.session.expiredSession expired without payment
transfer.createdAffiliate commission transfer created in Stripe Connect
transfer.failedCommission transfer failed; see failure_code

Webhook configuration is in your Merchant Dashboard under Settings → Webhooks.


Error Codes

HTTP StatusCodeDescription
400invalid_planThe plan_id does not exist or is inactive
400invalid_affiliate_tokenThe affiliate_token is malformed or expired
401unauthorizedMissing or invalid bearer token
403insufficient_scopeToken lacks required scope (mpp:write)
422checkout_failedStripe returned an error creating the session
429rate_limitedToo 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