Get started
Build with AI
Everything an AI coding assistant needs to integrate 9in correctly: context files, specs and a prompt to start from.
AI coding assistants integrate 9in well when they read the right context first. Everything in these docs is available as plain text built for that.
#Give your assistant the docs
| Link | What it is | Use it when |
|---|---|---|
https://9in.io/llms.txt | An index of every page with a one-line summary, plus the facts most often gotten wrong | The assistant can browse: it reads the index, then the pages it needs |
https://9in.io/llms-full.txt | All pages in one Markdown file | You paste or attach context once |
https://9in.io/docs/<page>.md | One page in Markdown (or Copy page as Markdown at the top of any page) | You want a focused context, such as one guide |
https://9in.io/openapi.json | The Management API as OpenAPI 3.1 | Generating API clients or calls |
https://9in.io/schemas/… | JSON Schemas: webhook events, adapter protocol, theme manifest | Typing webhook handlers and adapters |
<issuer>/.well-known/openid-configuration | Your tenant's live OpenID Connect metadata | Configuring any OIDC library |
The TypeScript SDK ships its own type definitions, so editors and assistants see every option of @9in-io/sdk as they type.
#A prompt to start from
Fill in the brackets and paste this into your assistant:
Add sign-in with 9in to this [Next.js / Express / Laravel / React / iOS] app.
Read https://9in.io/llms.txt first, then the guide for this kind of app and
https://9in.io/docs/reference/tokens.md.
Our tenant:
- Issuer (sandbox while we develop): https://[tenant]-sandbox.9in.io
- Application client ID: [app_…] (client secret in the env var NINE_CLIENT_SECRET, if any)
- Callback URL: [http://localhost:3000/callback]
- Our API's audience: [https://api.example.com], scopes: [orders:read]
Requirements:
- Use the official 9in SDK for this stack if there is one, otherwise a certified
OpenID Connect library. Use authorization code + PKCE; never the implicit flow.
- Read configuration from environment variables (NINE_ISSUER, NINE_CLIENT_ID, …).
- Verify access tokens in the API: signature via the issuer's JWKS, iss, aud, exp, scopes.
- Add sign-in, sign-out, a protected page and one protected API route, and tell me which
URLs to add to the application in the 9in console.#Facts assistants get wrong
Give these to an assistant that is guessing, or check its work against them:
- There is no client secret in browsers or mobile apps. Single-page and native apps are public clients: authorization code + PKCE (S256). Never put a client secret in front-end code.
- The issuer has no path. It is
https://<tenant>.9in.io(or a custom domain), not…/oauthor…/v1. Endpoints come from<issuer>/.well-known/openid-configuration. - Access tokens are for APIs, ID tokens are for the app. Send the access token to your API; don't verify ID tokens there. Request access tokens for your API with
audience=<API identifier>; without it, the access token'saudis your client ID. - Access tokens are JWTs with
typ: at+jwt, signed with the algorithm of the tenant's key (RS256 by default, but ES256, EdDSA or HMAC are possible). Don't hard-code RS256; take the algorithm from the key. Some APIs use opaque tokens (9in_at_…), which must be introspected. - Allowed web origins must include a single-page app's origin, or the browser's token request fails with a CORS error.
- The Management API is on the tenant host:
https://<tenant>.9in.io/api/v1/…, with a client-credentials token that hasmanagement:*scopes. There is no API key. - User fields differ between input and output in the Management API: you send
emailVerified,phoneandphoneVerified; you get backemail_verified,phone_numberandphone_number_verified. - Webhooks and adapter calls are signed with
9in-signature: t=<unix seconds>,v1=<hex>where the HMAC-SHA256 coverst + "." + METHOD + "." + path + "." + rawBody. Verify against the raw body, not re-serialized JSON. Event ids repeat on retries: process each once. - Sandbox and production share configuration but not users.
<tenant>-sandbox.9in.ioaccepts any password and the code000000; production users never appear there.