Synq Docs
Management APIToken gates

Test a token gate or a draft rule

Checks a gate (`gate`), or a rule not saved yet (`rule`, with an optional `schedule`), against wallets (`wallets`, at most 10 addresses) or a user's wallets in a brand (`user` and `brand`), as a sign-in would, at `at` (an ISO time, for the window; now when left out), with what was read in the last minute unless `fresh`. Answers what each condition came to, how many reads it cost, and the refusal page's words for it. A draft is read from the chain as saving it would read it (400 at the path of what isn't what its condition says, 503 when the chain can't say), so it is tested as the gate it would be. Saves nothing. Wants the org's plan to have token gating (`auth.token_gating`, 403 `plan_feature_unavailable` otherwise), since every test may read the chain through Synq's own key. Needs `org.tokenGates.view`, and `org.users.view` to test a user, which is recorded as `user.token_gate_dry_run` (a test against addresses reads only public chain data, and isn't). Limited per org (`token_gate.dry_runs`), and reads the chain from the org's own budget (`token_gate.org_reads`), never a brand's sign-ins'.

POST/v1/orgs/{org}/token-gates/check

Checks a gate (gate), or a rule not saved yet (rule, with an optional schedule), against wallets (wallets, at most 10 addresses) or a user's wallets in a brand (user and brand), as a sign-in would, at at (an ISO time, for the window; now when left out), with what was read in the last minute unless fresh. Answers what each condition came to, how many reads it cost, and the refusal page's words for it. A draft is read from the chain as saving it would read it (400 at the path of what isn't what its condition says, 503 when the chain can't say), so it is tested as the gate it would be. Saves nothing. Wants the org's plan to have token gating (auth.token_gating, 403 plan_feature_unavailable otherwise), since every test may read the chain through Synq's own key. Needs org.tokenGates.view, and org.users.view to test a user, which is recorded as user.token_gate_dry_run (a test against addresses reads only public chain data, and isn't). Limited per org (token_gate.dry_runs), and reads the chain from the org's own budget (token_gate.org_reads), never a brand's sign-ins'.

Authorization

bearer
AuthorizationBearer <token>

An org API key (sk_live_…, sk_test_…), or an access token from the Synq issuer (the synq brand, on the accounts host) for this API.

In: header

Path Parameters

org*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

application/problem+json

curl -X POST "https://example.com/v1/orgs/string/token-gates/check" \  -H "Content-Type: application/json" \  -d '{}'
{  "result": "string",  "schedule_state": "string",  "wallets": [    "string"  ],  "tree": {    "type": "string",    "path": "string",    "status": "string",    "checked": true,    "conditions": [      {        "type": "string",        "path": "string",        "status": "string",        "checked": true,        "held": "string",        "decimals": 0,        "count": 0,        "owned": true,        "listed": true      }    ]  },  "reads": 0,  "cached": 0,  "explanation": [    "string"  ]}

Change a token gate PATCH

Its name, rule, schedule, message, whether it is on, or where it applies. `rule` replaces the whole tree, read from the chain again as on making a gate; `schedule: null` and `refusal_message: null` clear them; `brands` and `apps` each replace their list. The next sign-in or refresh at an app it applies to checks the change. Turning a gate on checks its rule's chains again (400), and needs a chain where the rule reads one (409 `token_gates_unavailable`). Needs `org.tokenGates.edit`. Changing its rule or schedule, turning it on, or naming brands or apps also wants a plan with token gating (403 `plan_feature_unavailable`), so an org that moved to a plan without it can still turn one off, rename it, clear its message, empty its lists or delete it. Recorded as `token_gate.updated`.

Gate sign-in on what wallets hold POST

A gate on brands, apps or both: signing in to one of them, the person's wallets must meet its `rule`, or a page tells them why not (with `refusal_message` first) and the app gets `access_denied`. `rule` is a tree of `all` and `any` groups (at most 3 deep, each with 1 to 20 children, 20 conditions in all) of conditions on the wallets on the person's account in the brand: `token` (hold at least `min_amount` of a mint, every account and compressed balance of it counted), `collection` (hold at least `min_count` NFTs of a verified Core or Token Metadata collection, compressed and Core NFTs included), `nft` (hold one NFT) and `allowlist` (have a wallet on a list of at most 1000 addresses a gate, never shown to anyone). `token` and `collection` count every wallet together (`wallets: combined`, the default) or one alone (`single`). Each condition names its `chain`, which must be one this API reads (the list's `chains`) unless it is an allowlist. Synq reads every token, collection and NFT the rule names from the chain as it is written (400 for one that isn't what its condition says, at its path, such as `rule.root.conditions.1.collection`; 503 when the chain can't be read), once nothing else in the request is wrong and from the org's own reads (`token_gate.org_reads`, as its dry runs; 429 once they're spent), and keeps their names as each condition's `display`. `schedule` is an optional window in an IANA time zone, open at one end or both, with what happens `outside` it: `let_in` (the gate doesn't apply) or `refuse` (the app is closed to everyone). A sign-in reads at most 40 conditions from the chain across every enabled gate on an app (409 `conflict` naming the app otherwise). Gates are checked at every sign-in and on every refresh, where a refusal or a closed window ends the app's grant (`invalid_grant`), so access ends within one access token's life; what can't be read refuses a sign-in, and answers a refresh 503 `temporarily_unavailable` with the grant kept. What wallets hold is kept for a minute. Every check is recorded as `user.token_gate_checked`. At most 100 gates per org. Needs `org.tokenGates.edit`, a plan with token gating (403 `plan_feature_unavailable` otherwise, naming the plan in `required_plan`) and, for a rule that reads a chain, an API that reads one (409 `token_gates_unavailable` otherwise). Recorded as `token_gate.created`.