HomeProduct DocsAPI ReferenceChangelog
RecurlyAPI GuidesRecurly.jsWebhooksAPI ReferenceSupportBook demo
Product Docs

Using a token

Pass a Recurly.js token (token_id) to the Recurly API in place of raw payment details — code samples, the endpoints that accept it, and token rules.

Once Recurly.js encrypts card data and returns a token (token_id), your server passes that token to the Recurly API in place of raw payment details — so sensitive data never touches your servers and you stay out of PCI scope. This guide covers creating a purchase with a token, the endpoints that accept one, and the token's lifespan, reuse, and security rules.
Warning Tokens expire 20 minutes after creation. Move each one from browser to backend to Recurly quickly — once a token expires, it can't be recovered.
Note This guide assumes you've integrated Recurly.js and have a token_id to work with. See the Recurly.js overview for how tokens are created.

Why use tokens

Faster PCI compliance SAQ-A level — no sensitive card data touches your servers.
Consistent across endpoints The same token_id works for purchases, subscriptions, or standalone billing-info updates.
Safe to retry Tokens can be reused within the 20-minute window, simplifying idempotent flows and error recovery.

Create a purchase with a token

Pass the token as billing_info.token_id on the request. Recurly swaps it for the underlying card or bank details and completes the call.

purchase = {
  currency: "USD",
  account: {
    code: account_code,
    billing_info: { token_id: rjs_token_id }
  },
  subscriptions: [{ plan_code: plan_code }]
}
invoice_collection = @client.create_purchase(body: purchase)
const purchaseReq = {
  currency: 'USD',
  account: {
    code: accountCode,
    billingInfo: { tokenId: rjsTokenId }
  },
  subscriptions: [{ planCode }]
};
const invoiceCollection = await client.createPurchase(purchaseReq);
purchase = {
    "currency": "USD",
    "account": {
        "code": account_code,
        "billing_info": {"token_id": rjs_token_id},
    },
    "subscriptions": [{"plan_code": plan_code}],
}
invoice_collection = client.create_purchase(purchase)
PurchaseCreate purchase = new PurchaseCreate()
  .currency("USD")
  .account(new AccountPurchase()
      .code(accountCode)
      .billingInfo(new BillingInfoCreate().tokenId(rjsTokenId)))
  .subscriptions(List.of(new SubscriptionPurchase().planCode(planCode)));

InvoiceCollection collection = client.createPurchase(purchase);
var purchaseReq = new PurchaseCreate {
  Currency = "USD",
  Account = new AccountPurchase {
    Code = accountCode,
    BillingInfo = new BillingInfoCreate { TokenId = rjsTokenId }
  },
  Subscriptions = new List<SubscriptionPurchase> {
    new SubscriptionPurchase { PlanCode = planCode }
  }
};
InvoiceCollection collection = client.CreatePurchase(purchaseReq);

Token rules and security

RuleDetail
LifespanValid for 20 minutes from creation.
ReuseCan be used multiple times during that window (for example, account + subscription + one-time charge).
StorageThe token lives only in the Recurly vault; once it expires it can't be recovered.
TransportSend it to your server over HTTPS only — treat it like any auth credential.
Tip If you receive transaction_error.code = invalid_token, request a fresh token from Recurly.js and retry.

Endpoints that accept a token

Attach token_id inside billing_info on any of these:

Attach the token like so:

"billing_info": {
  "token_id": "1d1e4f0447c2b7e6d2f6cbf5c4b2c9aa"
}

Recurly swaps the token for the underlying card or bank details and completes the request while you stay out of PCI scope.

What's next


Did this page help you?