Get started

Build with AI

Everything an AI coding assistant needs to integrate 9in correctly: context files, specs and a prompt to start from.

View .md llms.txt

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

LinkWhat it isUse it when
https://9in.io/llms.txtAn index of every page with a one-line summary, plus the facts most often gotten wrongThe assistant can browse: it reads the index, then the pages it needs
https://9in.io/llms-full.txtAll pages in one Markdown fileYou paste or attach context once
https://9in.io/docs/<page>.mdOne 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.jsonThe Management API as OpenAPI 3.1Generating API clients or calls
https://9in.io/schemas/…JSON Schemas: webhook events, adapter protocol, theme manifestTyping webhook handlers and adapters
<issuer>/.well-known/openid-configurationYour tenant's live OpenID Connect metadataConfiguring 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 …/oauth or …/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's aud is 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 has management:* scopes. There is no API key.
  • User fields differ between input and output in the Management API: you send emailVerified, phone and phoneVerified; you get back email_verified, phone_number and phone_number_verified.
  • Webhooks and adapter calls are signed with 9in-signature: t=<unix seconds>,v1=<hex> where the HMAC-SHA256 covers t + "." + 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.io accepts any password and the code 000000; production users never appear there.