---
title: "One-call signup: issues a provisional key and emails a magic verification link."
method: POST
path: "/v1/keys"
tags: ["self-serve"]
---

# One-call signup: issues a provisional key and emails a magic verification link.

`POST /v1/keys`

## Request

- Base URL: `https://api.mapmap.ai`
- URL: `https://api.mapmap.ai/v1/keys`
- Auth: none declared

## Request body

- IssueKeyRequest: Body for `POST /v1/keys`.
  - `accept_tos` unknown
  - `allowed_origins` string[], nullable: Origins this key may be called from, e.g. `["https://app.example.com", "https://*.staging.example.com"]`. At most 20; each is `scheme://host[:port]` with no path, and a wildcard may only stand for a single subdomain label. Omit for an unrestricted key, the default, and what a server-to-server integration wants.
  - `device_id` string, nullable: Email-less issuance only: an opaque, stable id for the app install (the apps' install id). Never stored as sent; only its hash is used, as a per-install daily issuance budget beside the per-IP one. At most 128 characters. Optional, and ignored when an email is given.
  - `email` string, nullable: Email address; becomes the (lowercased) identity of the key. Optional ONLY for the MapMap apps' own labels ([`identity::EMAIL_OPTIONAL_LABELS`]), which then get an email-less `anonymous` key; every other caller must send one.
  - `label` string, nullable: Optional human-readable label for this key (shown on the account page, e.g. `"nightly-dispatch-agent"`). Defaults to the email.
  - `scope` string, nullable: `"full"` (the default) or `"maps"`. A `maps` key may draw tiles, read styles/fonts/sprites, geocode and read its own status, and nothing else.
  - `source` string, nullable: Optional channel tag naming where this signup came from (`"chatgpt"`, `"agent-recipe"`, `"cursor"` …). Lowercased and restricted to `[a-z0-9._-]`, at most 40 characters; anything else is dropped, never rejected, attribution must not break signups.

## Response `201`

Provisional key issued; the `key` field is shown once only

- IssuedKeyResponse: Response for `POST /v1/keys`, the only time the key is revealed.
  - `allowed_origins` string[], nullable: The canonical origin allow-list stored for this key, echoed back so the caller can see exactly what was accepted (ports and case are normalised, duplicates dropped). Absent on unrestricted keys.
  - `calls` integer, required: Call allowance: in total until verified for a `provisional` key, per calendar month for `anonymous` and `verified` keys.
  - `claim_url` string, nullable: Zero-authority claim pointer for the HUMAN behind this agent: the page shows a masked email and offers to send a sign-in link. Safe to print in chat or logs; it grants nothing by itself. Present only when the deployment has a console (`SN_CONSOLE_URL`).
  - `display_to_user` string, nullable: Sentence for the agent to show its human verbatim (contains the claim URL, never the key). Present only alongside `claim_url`.
  - `expires_in_h` integer, required: Hours until the provisional key expires unverified; 0 for keys that do not expire.
  - `key` string, required: The full API key (`snk_…`). Shown once, never again.
  - `key_id` string, required: Key id (UUID), for `/v1/keys/self` correlation and admin ops.
  - `scope` string, nullable: `"maps"` when the key was minted map-scoped; absent for the full surface.
  - `state` string, required: `provisional` at an ordinary issuance; `anonymous` for an email-less app key; `verified` for the store-review identity.
  - `tos` string, required: Terms-of-service URL that was accepted.
  - `verify` string, required: What happens next.

## Other responses

- `400`: ToS not accepted (body echoes the `tos` URL), invalid/disposable email, or rejected `allowed_origins`/`scope` (body carries `problems[]`)
- `429`: Issuance velocity exceeded: per IP or per install (`limit_per_day`), per address per hour for a key without an email (`limit_per_hour`), or the global hourly ceiling

---

[API](https://skmtc.dev/mapmap/apis/sn-gateway.md) · [All operations](https://skmtc.dev/mapmap/apis/sn-gateway/llms.txt) · [OpenAPI document](https://skmtc.dev/mapmap/apis/sn-gateway/revisions/2293be8b4c38?raw)
