API reference
Signet's public API is read-only and versioned: every endpoint answers a GET with JSON (one returns an SVG badge), and v1 only ever changes by adding things. It is what @signet/sdk reads.
Base URL
Every path below is relative to the deployment's /api/v1. The version is in the path; there is no version header.
curl -s "https://signet-web-pearl.vercel.app/api/v1/health"Authentication and API keys
No key is needed: anonymous callers can read everything. A key is a rate-limit identity, not a permission. Send it as a bearer token for the higher keyed budget, and keep it server-side. An invalid or revoked key is a 401, never silently anonymous.
curl -s -H "Authorization: Bearer sgk_…" "https://signet-web-pearl.vercel.app/api/v1/profiles/alice"Rate limits
Anonymous callers get 60 requests per minute per IP; a key raises that to 300 by default. Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds), so a client can pace itself. Over the limit is a 429 with Retry-After in seconds.
Errors
A response has either data or error, never both. Branch on error.code, a closed list; message is for logs and may change.
{ "error": { "code": "not_found", "message": "No profile for handle 'nobody'.", "details": {} } }| code | status | Meaning |
|---|---|---|
| bad_request | 400 | The request is malformed or a parameter is invalid. Do not retry. |
| unauthorized | 401 | An invalid or revoked API key was sent. Do not retry. |
| not_found | 404 | The resource does not exist (for a handle: it is not bound). Do not retry. |
| rate_limited | 429 | Over budget. Retry after the Retry-After header. |
| unavailable | 503 | A dependency (database, chain RPC, Horizon) could not answer. Retry with backoff. |
| internal | 500 | A bug in Signet. The response carries no internals. |
Pagination
Lists take limit (default 25, at most 100) and an opaque cursor. Pass meta.nextCursor back for the next page; it is null on the last one. A cursor is a position, not an offset, so items added while you page never repeat or shift a page. meta.truncated says a list may be partial (a capped read, or no layer able to answer), and meta.source which layer answered.
curl -s "https://signet-web-pearl.vercel.app/api/v1/profiles/alice/contracts?limit=25"
curl -s "https://signet-web-pearl.vercel.app/api/v1/profiles/alice/contracts?limit=25&cursor=<meta.nextCursor>"CORS and caching
Every response sends Access-Control-Allow-Origin: *, so a browser on any site can call the API; the API is read-only, so there are no credentials to protect. Cacheable answers carry a weak ETag and honour If-None-Match with a 304; errors are no-store.
Endpoints
Badges
Specifications
Health
Registry
Other
Profiles
The machine-readable document is at /api/v1/openapi.json. The full design rules, including what counts as a breaking change, are in docs/API_V1.md.