Access Code Tools

An access code is a pre-generated, single-use activation a creator hands out; redeeming it claims a pending subscription.

An access code is a pre-generated, single-use activation a creator hands out; redeeming it claims a pending subscription. These tools mint codes singly or in bulk, list them and revoke the ones that should no longer work.

Tools

Queue a bulk access-code generation batch. Returns a job_id immediately — poll get_job_status for completion.

Bulk-generate access codes for a plan. The underlying job can take minutes for large batches, so the tool returns a job_id immediately; clients poll get_job_status until status=completed. The access_code.generated event emits once per batch when the worker finishes.

Billing model: generation is free. The Stripe metered overage triggers on redemption when the creator's tier free allotment is exhausted. The response embeds a preview so callers can still surface the worst-case cost ("if all N get redeemed"). For a cost-only query, call preview_access_code_cost.

Delivery goes through the creator's connector chat (the Telegram bot today), never through this tool's response. export_type must be file (a CSV sent to the creator) or messages (one forwardable message per code) — both require the creator account to have a linked connector identity. Agents that need programmatic access must also call list_access_codes after the batch completes.

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Fires one event

Delivered to every endpoint subscribed to it once the change is made.

Annotations

DestructiveOpen world

A client that honours annotations asks a person before running it. It reaches beyond Subscriby: a connector, a provider or a member.

Arguments

plan_id*string

UUID of the plan to attach the generated codes to.

quantity*integer

How many access codes to generate (1-1000).

export_type*string

How the job delivers the codes to the creator — file (CSV via bot) or messages (one per code via bot). Required.

expiry_preset*string

Required. One of no_expiry, 1_day, 1_week, 1_month, 1_year, custom.

custom_expiry_amountintegeroptional

When expiry_preset=custom, the amount of custom_expiry_type units. Required when preset=custom.

custom_expiry_typestringoptional

When expiry_preset=custom, one of days/weeks/months/years. Required when preset=custom.

consentbooleanoptional

Required and must be true when export_type=messages — acknowledges that one message per code will be sent to the creator's connector chat.

What it returns

{  "data": {    "job_id": "0a4e7b96-c358-4d12-9f6b-25a8013ce74f",    "status": "queued",    "enqueued_at": "2026-05-18T10:05:00Z",    "plan_id": "c4e82f16-93a7-4d5b-b81c-6e0f27a94d3b",    "quantity": 50,    "preview": {      "free_remaining": 3,      "chargeable_quantity": 47,      "cost": "1.41"    }  }}

Poll get_job_status with the returned job_id until status is completed or failed. It always reaches one of the two.

On completion the job's result carries the batch summary:

{
  "plan_id": "c4e82f16-93a7-4d5b-b81c-6e0f27a94d3b",
  "plan_name": "Premium Monthly",
  "count": 50,
  "export_type": "file",
  "expires_at": null,
  "delivered": true,
  "delivery_error": null
}

Generation and delivery succeed separately

The codes are written first, then handed to the creator over their connector. If that delivery fails — the bot is disconnected, the platform is down — the job still completes: the codes exist and are redeemable, and access_code.generated still fires. delivered goes false and delivery_error carries the reason, so you can tell the creator their CSV never arrived without anyone concluding the batch failed and generating it twice.

How it fails

VALIDATION_FAILED

quantity out of range, unknown export_type, missing consent when export_type=messages, missing custom_expiry_amount / custom_expiry_type when expiry_preset=custom, unknown expiry_preset, a batch for the same plan already in flight, or the underlying Action rejects the inputs.

RESOURCE_NOT_FOUND

unknown plan_id, or the plan belongs to a team outside the token's scope.

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks project-access-code:create.

One batch per plan at a time

Queueing a second batch for a plan whose previous one has not reported an outcome is refused with VALIDATION_FAILED, and the message names the live job_id to poll instead.

The worker deduplicates by creator, project and plan, so a second batch inside that window would be dropped without a word — handing you a job id for work that was never going to run. Refusing up front is the honest version of the same constraint.

Paginated list of access codes for a plan, with first/last-4 masked prefixes only — full codes are never surfaced.

List access codes for a plan. Requires plan_id, accepts an optional status filter (unredeemed, redeemed, expired, or all). Results are scoped to the caller's team.

Codes are returned with a masked prefix (first 4 + asterisks + last 4). The plaintext value is delivered to the creator's connector chat by bulk_generate_access_codes — the MCP layer is read-only on the secret itself.

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Annotations

Read-only

It reads and never changes anything.

Arguments

plan_id*string

UUID of the plan to list codes for.

statusstringoptional

Filter by code state. One of: unredeemed, redeemed, expired, all.

allunredeemedredeemedexpired
limitintegeroptional

Maximum codes to return per page (1..100).

min1max100
pageintegeroptional

1-indexed page number.

min1

What it returns

{  "data": [    {      "id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4",      "plan_id": "c4e82f16-93a7-4d5b-b81c-6e0f27a94d3b",      "code_masked": "A3F1****7Z9P",      "redeemed_at": null,      "expires_at": "2026-08-01T00:00:00Z",      "redeemed_by": null,      "created_at": "2026-05-18T10:05:00Z"    }  ],  "meta": {    "page": 1,    "limit": 25,    "total": 47,    "has_more": true,    "status": "unredeemed"  }}

How it fails

TOKEN_MISSING_ABILITY

token lacks project-access-code:view-any.

Preview the cost of generating access codes before queuing the batch. Returns free_remaining, chargeable_quantity, and cost.

Preview the cost of generating access codes before queuing the batch. Returns free_remaining, chargeable_quantity, and the resulting cost in the creator-tier currency so the agent can surface the charge to a human. Always call this first when quantity might exceed the creator tier free allotment — the generation tool refuses to run with chargeable codes unless the caller acknowledges overage.

The token behind the MCP session must hold it, or the call is refused with TOKEN_MISSING_ABILITY.

The REST endpoint and this tool share one action, so validation, permissions and events are identical.

Annotations

Read-only

It reads and never changes anything.

Arguments

plan_id*string

UUID of the plan the batch would be attached to.

quantity*integer

How many access codes the agent is considering generating (1-10000).

What it returns

{  "data": {    "plan_id": "c4e82f16-93a7-4d5b-b81c-6e0f27a94d3b",    "quantity": 50,    "preview": {      "free_remaining": 3,      "chargeable_quantity": 47,      "cost": "1.41"    },    "will_bill_overage": true  }}

How it fails

RESOURCE_NOT_FOUND

unknown plan_id, or the plan belongs to a team outside the token's scope.

VALIDATION_FAILED

quantity is outside the 1..10,000 range.

AUTHENTICATION_REQUIRED

no authenticated user on the request.

TOKEN_MISSING_ABILITY

token lacks project-access-code:create.

How is this guide?

On this page

Subscriby is a product designed by you — for you.No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request