Authentication & Tokens
Every request carries a personal access token that belongs to exactly one property. There is no account-wide token and no property id in the URL: the token is the property.
curl https://api.snipform.io/v2/property/signals/analytics/metrics \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"period":"last_7"}'Create a token
Section titled “Create a token”-
Open the property in the dashboard and go to API (
https://app.snipform.io/property/{property}/api). -
Click New token and fill in:
Field Options Name Anything that tells you later what uses it ( warehouse-sync,looker)Type API for a script or integration. MCP for an AI assistant (see below) Expires in 7 days, 30 days, 90 days, 1 year, or never Scopes API tokens only. Pick exactly what the integration needs -
Copy the token from the confirmation. It is shown once and never again. Store it like a password.
The token is bound to the property you created it on. It cannot reach sibling properties on the same account, and the property cannot be changed after creation; make a new token instead.
Scopes
Section titled “Scopes”Pick the smallest set that does the job. A token without a required scope gets a 403 with the scope named:
{ "code": 403, "status": "Forbidden", "data": { "message": "Missing scope: signals:write", "error_code": "forbidden" }}| Scope | Description shown in the dashboard |
|---|---|
signals:read | Read analytics, sessions, channels |
signals:write | Record events and acquisition data on sessions |
conversions:read | Read conversion definitions, funnels, segments |
conversions:write | Create and update conversions |
forms:read | Read forms and submissions (reserved, no endpoint uses it yet) |
shortlinks:read | Read short link groups, links, and clicks |
shortlinks:write | Create and update short links |
contacts:read | Read identified contacts and their sessions |
contacts:write | Identify, update, and delete contacts |
Scopes are fixed at creation. To change them, create a new token and revoke the old one.
Expiry and revocation
Section titled “Expiry and revocation”- An expired token is refused with 401. Nothing warns you ahead of time, so put the expiry in your own calendar or pick never for long-lived server integrations and rotate on your own schedule.
- Revoke on the API page takes effect immediately. Revoked tokens are gone from the list and every request with one returns 401.
- The list shows the tokens that are still live for the property, newest first.
Failure modes
Section titled “Failure modes”| HTTP | Message | Cause |
|---|---|---|
| 401 | Unauthenticated. | Header missing, token malformed, expired or revoked |
| 403 | Token is not scoped to a property. | The token was not issued through the property API page |
| 403 | Missing scope: ... | The route needs a scope the token does not carry |
| 404 | Token property no longer exists. | The property was deleted after the token was issued |
API tokens vs MCP tokens
Section titled “API tokens vs MCP tokens”The dashboard issues two kinds of token from the same screen. The type is derived from the scopes, not stored separately.
| API token | MCP token | |
|---|---|---|
| Scopes | The read/write scopes you choose | Exactly one: mcp:use, set automatically |
| Calls | The REST endpoints in this section | Only the MCP server at /mcp/{property} |
| Access | Whatever the scopes grant, including writes | Read-only analytics, by contract |
| Rate limit | None published | 60 requests per minute |
The two never cross over. An API token on the MCP endpoint is refused because it lacks mcp:use. An MCP token on a REST endpoint is refused because it lacks every REST scope; the one exception is GET /v2/property/overview, which checks no scope and answers any valid token.
Keeping tokens safe
Section titled “Keeping tokens safe”- One token per integration. When something leaks you revoke one thing, not everything.
- Never ship a token in browser code. Browser-side work goes through the tracker and forms libraries, which are unauthenticated by design.
- Treat the token like a database password: environment variables or a secrets manager, never source control.
- Reads and writes should usually be separate tokens. A reporting job does not need
contacts:write.