Authentication

Every request to the Synex API authenticates with a secret API key sent as a bearer token. Keys are pinned to a team, carry a set of abilities, and can be restricted to specific ontologies — so you can hand an integration exactly the access it needs and nothing more.

API keys

Keys are created and revoked from API Keys in the Synex application, and over the API itself at /v1/api_keys. Send the secret in the Authorization header on every request:

Authorization header

curl https://api.synexcloud.com/v1/me \
  -H "Authorization: Bearer synex_sk_..."

The key object carries id, name, abilities, scopes, metadata, last_used_at, expires_at, the rotation lineage (rolled_at, rolled_to, rolled_from) and created_at. The team a key is pinned to is not a field on it over /v1 — there is only ever one answer, and GET /v1/team is where to read it.

last_used_at is the field to sweep for: a key with a null or long-stale value is one nobody is using, and a key nobody is using is a credential you are carrying for no reason.

Expiry

A key may be given an optional expires_at at creation — any future instant, up to two years out. Past its expiry it stops authenticating; nothing warns you first, so treat the date as a deadline you schedule against rather than a notification you will receive.

Expiry is set once and cannot be pushed back. A deadline that can be extended is not a deadline, and rotating rather than extending is what rolling is for.

Over the API there is one extra rule: a key may not outlive the key that created it. See API keys.

Rolling a key

Rolling issues a new secret while the old one keeps working, so a deploy never lands in a window where neither secret authenticates. The old secret keeps working for 24 hours; redeploy inside that window and there is nothing to clean up.

Three details worth knowing before you build a rotation job on it:

  • The replacement does not inherit the rolled key's expiry. From the Synex application it is minted perpetual. Over the API the replacement instead inherits the calling key's expiry, so a self-roll cannot turn an expiring key perpetual — the one place the two surfaces deliberately disagree.
  • Rolling never extends a key. If the old key was already due to expire inside the next 24 hours, it keeps its own earlier deadline.
  • Rolling twice does not restart the window. Rotate at the pace of your deploys, not faster.

Rolling by id requires api_keys:write and that the target reaches no further than the caller. Rolling yourself through POST /v1/api_keys/self/roll needs no ability at all and is the recommended hygiene path.

Team pinning

Every key is pinned to the team it was created in, and all requests act on that team. Switching teams in the web app never changes what a key can see. If the key's creator leaves the team, the key stops working and requests fail with 401 api_key_team_revoked.

Abilities

A key carries a set of abilities, and each endpoint requires one. A request without the required ability fails with 403 insufficient_permissions.

  • Name
    templates:read / templates:write
    Type
    ability
    Description

    List and read templates · create, edit, fork, complete, and delete them.

  • Name
    ontologies:read / ontologies:write
    Type
    ability
    Description

    List and read ontologies, versions and drafts · instantiate templates, edit and publish drafts.

  • Name
    passports:read / passports:write
    Type
    ability
    Description

    Read, list, and download QR codes · create, update, and delete passports.

  • Name
    compositions:read / compositions:write
    Type
    ability
    Description

    Read presentation layouts · create and update them.

  • Name
    files:read / files:write
    Type
    ability
    Description

    Read file metadata, list directories, mint download links, preview spreadsheets · upload files, run multipart uploads, create folders.

  • Name
    imports:read / imports:write
    Type
    ability
    Description

    Inspect imports, their rows and the failed-row export · start imports and retry failed rows.

  • Name
    audit:read
    Type
    ability
    Description

    Query the audit log and read retention settings. The key owner must be a team admin or owner.

  • Name
    audit:write
    Type
    ability
    Description

    Update the audit retention window. Admin/owner owner required. Not granted by default.

  • Name
    team:read
    Type
    ability
    Description

    Read the team's identity and member roster. Not granted by default — the roster is personal data.

  • Name
    lab:read / lab:write
    Type
    ability
    Description

    Lab queries, DSL tools, runs, usage, catalog and exports · transforms, rollbacks, and enabling or disabling Lab (admin or owner).

  • Name
    events:read
    Type
    ability
    Description

    Read the change feed. Not granted by default.

  • Name
    api_keys:read
    Type
    ability
    Description

    List and read the team's API keys, secrets excluded. Not granted by default.

  • Name
    api_keys:write
    Type
    ability
    Description

    Mint, patch, revoke and roll the team's API keys. Not granted by default, and sensitive.

  • Name
    design:read / design:write
    Type
    ability
    Description

    Read the public-passport theme · update it. Not granted by default.

  • Name
    data_requests:read / data_requests:write
    Type
    ability
    Description

    List and read external data requests · create and revoke them. Not granted by default.

  • Name
    suppliers:read / suppliers:write
    Type
    ability
    Description

    Read suppliers and their requests · invite, link, request values, and map answers onto passports. Not granted by default.

  • Name
    webhook_endpoints:read
    Type
    ability
    Description

    List and read webhook endpoints and their delivery records. Not granted by default.

  • Name
    webhook_endpoints:write
    Type
    ability
    Description

    Create, update, delete endpoints and roll signing secrets. Not granted by default, and sensitive.

The default set is only four

templates:read, ontologies:read, passports:read and compositions:read. Every other ability above — every write, and every read marked not granted by default — has to be asked for explicitly when the key is minted. A key gets what you name and nothing more.

Each of the newer ones is out of the default for its own concrete reason. team:read returns member names and email addresses. design:write restyles every public passport the team has ever published. data_requests:write mints credentials that get mailed to third parties. suppliers:write can send requests for data out of the team altogether. audit:write moves a compliance setting. api_keys:read exposes the whole team's credential inventory, and api_keys:write can revoke any of it — including the calling key.

One operation needs no ability at all: POST /v1/api_keys/self/roll rotates the calling key, and a replacement with identical abilities escalates nothing. A key holding none of the above can still rotate itself, which is the point.

The two sensitive abilities

webhook_endpoints:write lets a key point a destination at your team's data and roll a secret out from under a running consumer. api_keys:write lets a key mint, narrow, revoke and rotate the team's credentials — including the one making the call.

Minting is subset-constrained, which is what makes the second one safe to offer at all: a key may only grant abilities it already holds, may only narrow an ontology scope, may not outlive its parent, and inherits its team rather than choosing one. Rolling carries the same constraint, because rolling returns a secret. A key therefore cannot widen its own reach. See the security model.

Ontology scopes

Abilities that touch passport data — passports:*, compositions:*, and imports:* — can be restricted to specific ontologies when the key is created. A scoped key:

  • can act only on resources inside its listed ontologies; anything else fails with 403 ability_not_scoped_to_resource;
  • cannot use list endpoints that span the whole team (for example GET /v1/imports) — fetch those resources by id instead;
  • cannot reach team-global resources that have no ontology to match against.

files:* is deliberately not scopable: a file belongs to the team, not to an ontology, so there is nothing for a scope to match.

The same reasoning rules out every one of the newer abilities — audit:*, team:read, events:read, design:*, data_requests:*, suppliers:*, webhook_endpoints:* and api_keys:* are all unscopable. Design and audit settings are team singletons; the member roster is the team; the event feed is team-global; an endpoint belongs to the team rather than any one ontology; and a key is a team credential whose own scopes are the thing being described.

A key carrying an ontology-scoped grant is rejected on these endpoints rather than quietly reading everything — an over-broad scope should be an error you see, not a silence you trust.

Use scoped keys for integrations that should only ever see one product line.

Role-gated endpoints

Four areas additionally require the key's owner to be a team admin or owner at request time. Revoking the role instantly disables these calls, regardless of the key's abilities:

The two audit ones fail with 403 audit_role_required. Either code is distinct from the 403 insufficient_permissions a missing ability returns, so you can tell "this key was never granted that" from "this key's owner lost the role" without guessing at which to fix.

One endpoint where a role gate might reasonably be expected and deliberately is not: PATCH /v1/design. Any member of a team may edit its branding in the Synex application, and making the API stricter than the surface it mirrors would leave an integration unable to do what the person configuring it can already do by hand. The non-default design:write ability is the gate here.


GET/v1/me

Inspect the current key

Returns the context the key is acting in — its pinned team, the abilities it carries, and any ontology scopes. Call this to verify a key before relying on it, or to discover what an integration is allowed to do.

This endpoint requires only a valid key (no specific ability).

Request

GET
/v1/me
curl https://api.synexcloud.com/v1/me \
  -H "Authorization: Bearer $SYNEX_API_KEY"

Response

{
  "object": "api.key",
  "team": { "id": 42, "name": "Acme Batteries" },
  "abilities": [
    "passports:read",
    "passports:write",
    "imports:read",
    "imports:write"
  ],
  "scopes": {
    "ontologies": ["ontology_00a1b2c3d4e5f607"]
  }
}

GET/v1/ping

Check connectivity

An unauthenticated connectivity check — the one endpoint in v1 that needs no key at all. Use it to confirm reachability, DNS and TLS before you start debugging credentials.

The response echoes the request_id, which is the same value the X-Request-Id header carries and the one to quote in a support request.

Request

GET
/v1/ping
curl https://api.synexcloud.com/v1/ping

Response

{
  "object": "api.ping",
  "message": "pong",
  "request_id": "req_9f2c1ab34d5e6f70"
}

Was this page helpful?