Payments

Create subscription plan

Changed on

Creates a recurring-payment subscription plan record. This stores SDP backend state and Solana subscriptions program identifiers; it does not by itself create the on-chain plan.

post/v1/payments/subscription-plans

Request

  • Base URL
    http://localhost:8787
  • URL
    http://localhost:8787/v1/payments/subscription-plans
  • Auth
    HTTP bearer

Headers

x-project-idstring

Required for dashboard sessions. API keys use their assigned project.

Example:prj_example
Idempotency-Keystring

Optional, and honored when sent. 1-255 printable ASCII characters; send a UUID per logical operation and reuse it on every retry. Within 24 hours, a retry with the same key and the same request returns the stored status and body with the response header Idempotent-Replayed: true. Keys are scoped to the credential: within 24 hours, the same key with a different request, or from a different credential, returns 422 IDEMPOTENCY_KEY_REUSED; after that, the same key from a different credential runs as a new request. A rotated API key is a new credential, so after any rotation read the resource with GET to see whether the original request ran, and never resend a money request under the new credential without checking first. A key whose original request is still running returns 409 IDEMPOTENCY_KEY_IN_FLIGHT with Retry-After. A 400, 401, 403, 409 or 429 refusal is not stored, so the same key runs again once the cause is fixed. Access is checked before the key on every request, so a refused request never claims the key, and a credential that has since lost access to the named resource gets 403 instead of the stored response. A replay is a snapshot of the original response: read the current state with GET instead of sending the request again. If the original request never recorded its outcome (it crashed), a same-key retry gets 409 IDEMPOTENCY_KEY_IN_FLIGHT until 15 minutes plus the route's lease have passed since the original was sent (about 16 minutes, or about 20 for transfer batches), then 409 IDEMPOTENCY_KEY_OUTCOME_UNKNOWN with no Retry-After, as does every later retry with that key: read the resource with GET to see whether it ran, then send again with a new key. A 5xx is stored and replayed like any other answer; retry it with a new key.

Example:idempotency_example_12345

Request body

ownerWalletIdstring required

Custody wallet that owns the Solana subscription plan.

tokenstring required

Token mint address. Native SOL is not expected for program-backed subscriptions.

amountstring required

Recurring charge amount in UI units.

periodHoursinteger required

Billing period length in hours.

programPlanIdstring

Unsigned 64-bit decimal program plan identifier used in the Solana subscriptions PDA seed. Defaults to a generated nonzero value.

planPdastring

On-chain plan PDA once created.

destinationAddressstring

Optional destination owner address allowed by the on-chain plan.

pullerWalletIdstring

Optional SDP custody wallet allowed to pull subscription payments.

metadataUristring uri

Optional plan metadata URI.

status'draft' | 'active' | 'archived'

Subscription plan status.

Example request

{
  "ownerWalletId": "wal_merchant",
  "token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "amount": "25.00",
  "periodHours": 720,
  "programPlanId": "17014118346046923173",
  "planPda": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
  "destinationAddress": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
  "pullerWalletId": "wal_collector",
  "metadataUri": "https://example.com/subscriptions/monthly-usdc.json",
  "status": "active"
}

Response

Subscription plan created

Example response

{
  "data": {
    "subscriptionPlan": {
      "id": "psp_example",
      "organizationId": "org_example",
      "projectId": "prj_example",
      "ownerWalletId": "privy_wallet_123",
      "ownerAddress": "So11111111111111111111111111111111111111112",
      "amount": "100.00",
      "periodHours": 720,
      "programPlanId": "17014118346046923173",
      "planPda": "So11111111111111111111111111111111111111112",
      "destinationAddress": "So11111111111111111111111111111111111111112",
      "pullerWalletId": "privy_wallet_123",
      "pullerAddress": "So11111111111111111111111111111111111111112",
      "status": "active",
      "createdAt": "2025-01-01T00:00:00.000Z",
      "updatedAt": "2025-01-01T00:00:00.000Z"
    }
  },
  "meta": {
    "requestId": "req_example",
    "timestamp": "2025-01-01T00:00:00.000Z"
  }
}

Changes

    • warning

      added the new CUSTODY_POLICY_REFUSED enum value to the / response property for the response status

    • warning

      added the new CUSTODY_POLICY_REFUSED enum value to the / response property for the response status

    • warning

      added the new CUSTODY_POLICY_REFUSED enum value to the / response property for the response status

    • warning

      added the new CUSTODY_POLICY_REFUSED enum value to the / response property for the response status

    • warning

      added the new CUSTODY_POLICY_REFUSED enum value to the / response property for the response status

    • warning

      added the new CUSTODY_POLICY_REFUSED enum value to the / response property for the response status

    • warning

      added the new CUSTODY_POLICY_REFUSED enum value to the / response property for the response status

    • warning

      added the new RPC_UNAVAILABLE enum value to the / response property for the response status

    • warning

      added the new RPC_UNAVAILABLE enum value to the / response property for the response status

    • warning

      added the new RPC_UNAVAILABLE enum value to the / response property for the response status

    • warning

      added the new RPC_UNAVAILABLE enum value to the / response property for the response status

    • warning

      added the new RPC_UNAVAILABLE enum value to the / response property for the response status

    • warning

      added the new RPC_UNAVAILABLE enum value to the / response property for the response status

    • warning

      added the new RPC_UNAVAILABLE enum value to the / response property for the response status

    • warning

      added the new SPONSORED_RENT_OVER_CAP enum value to the / response property for the response status

    • warning

      added the new SPONSORED_RENT_OVER_CAP enum value to the / response property for the response status

    • warning

      added the new SPONSORED_RENT_OVER_CAP enum value to the / response property for the response status

    • warning

      added the new SPONSORED_RENT_OVER_CAP enum value to the / response property for the response status

    • warning

      added the new SPONSORED_RENT_OVER_CAP enum value to the / response property for the response status

    • warning

      added the new SPONSORED_RENT_OVER_CAP enum value to the / response property for the response status

    • warning

      added the new SPONSORED_RENT_OVER_CAP enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_DESTINATION_CHANGED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_DESTINATION_CHANGED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_DESTINATION_CHANGED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_DESTINATION_CHANGED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_DESTINATION_CHANGED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_DESTINATION_CHANGED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_DESTINATION_CHANGED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_NOTHING_TO_RETRY enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_NOTHING_TO_RETRY enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_NOTHING_TO_RETRY enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_NOTHING_TO_RETRY enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_NOTHING_TO_RETRY enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_NOTHING_TO_RETRY enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_NOTHING_TO_RETRY enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RETRY_CLAIMED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RETRY_CLAIMED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RETRY_CLAIMED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RETRY_CLAIMED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RETRY_CLAIMED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RETRY_CLAIMED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RETRY_CLAIMED enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RUN_EXISTS enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RUN_EXISTS enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RUN_EXISTS enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RUN_EXISTS enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RUN_EXISTS enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RUN_EXISTS enum value to the / response property for the response status

    • warning

      added the new TRANSFER_BATCH_RUN_EXISTS enum value to the / response property for the response status