Build a deep link
/v1/projects/{project}/distribution/deep-link in the Distribution API.
Builds a start link against the project's connected installation. The payload depends on which query parameter you pass (at most one; an access code wins over a plan, and a plan over a custom parameter):
| Query parameter | Resulting payload | Acted on by the bot? |
|---|---|---|
access_code | the code verbatim | Yes: redeemed on open. |
plan_id | the plan's bare UUID | Yes: opens that plan's checkout flow. |
custom | the caller-supplied string | No, see below. |
| (none) | project_<uuid> | No: falls through to the project home, which is the intent. |
Only a bare UUID is acted on. The bot acts on a start payload only when it is a bare UUID: it is matched against the project's plans first, then tried as an access code.
custompayloads and the defaultproject_<uuid>do not match that shape, so the bot ignores them and opens its home screen.customis therefore a passthrough for your own tracking: the platform delivers it and you can read it off the update in a webhook consumer, but Subscriby neither stores it nor attaches it to the member.
curl "https://api.subscriby.net/v1/projects/$PROJECT_ID/distribution/deep-link?plan_id=$PLAN_ID" \ -H "Authorization: Bearer $SUBSCRIBY_TOKEN"Requires ability
The token must hold this ability, or the call is refused with 403.
MCP tool
Runs the same action from an agent, behind the same ability.
Authorization
bearerToken A personal access token minted on the dashboard under Settings, then Tokens, sent as Authorization: Bearer sbt_live_…. The token carries the abilities each endpoint lists under Requires ability and is frozen to one team.
In: header
Path Parameters
The project, resolved by the route binder.
uuidQuery Parameters
A plan of this project; the link then opens that plan's checkout. Answers 404 for a plan outside the project. Ignored when access_code is also sent.
uuidAn access code, carried verbatim and redeemed when the link is opened. Wins over plan_id and custom.
length <= 64Your own tracking string, 1 to 64 characters of letters, digits, underscore or hyphen. Delivered by the platform but not acted on or stored by Subscriby. Used only when neither access_code nor plan_id is sent.
^[A-Za-z0-9_-]{1,64}$Responses
200OKapplication/json
The bot URL, the start payload and the assembled deep link.
401UnauthorizedAUTHENTICATION_REQUIREDapplication/json
The request carries no bearer token, or one that is revoked, malformed, or minted for another environment (an sbt_test_ token on production).
403ForbiddenTOKEN_MISSING_ABILITYapplication/json
The token is valid but does not carry the ability this endpoint requires; error.context.required_ability names the one to grant. An endpoint that also checks who owns a row or which tier the account is on answers FORBIDDEN, TEAM_TIER_REQUIRED or CONNECTOR_TIER_REQUIRED with the same status, and says so in its own description.
404Not foundRESOURCE_NOT_FOUNDapplication/json
An id in the path names nothing the token can see. TENANT_MISMATCH: the project sits outside the token's scope:project: allow-list, or the token carries no team scope. Both answer 404 rather than 403 so that existence outside the token's scope cannot be inferred.
On this endpoint: RESOURCE_NOT_FOUND: when plan_id does not belong to this project.
422Validation failedVALIDATION_FAILEDapplication/json
The payload broke a rule, and error.fields maps each offending key to its messages. A refusal from the domain, such as a plan that cannot go on sale or a member who cannot be removed, uses the same code with error.message saying why and no fields.
On this endpoint: VALIDATION_FAILED: with reason: no_bot_attached when the project has no connected installation to link to. VALIDATION_FAILED: on plan_id when it is not a UUID, or on custom when it is not 1 to 64 characters of letters, digits, underscore or hyphen.
429Too many requestsRATE_LIMITEDapplication/json
The token has spent its 300 requests a minute or 10,000 an hour; Retry-After says when the next one is accepted.
How is this guide?
Last updated on