Journey. As a developer (human or agent-operated), I want to reach a running
Inaya Labs service and make one authenticated request, so that I can confirm my
environment before building anything real.
Every integration starts the same way: pick an environment, prove a service is alive, present your credentials, and make one small authenticated call. This guide walks that path end-to-end. Nothing here writes data.
Prerequisites
- One of the environments below is reachable from your machine (local dev stack, or the
shared dev subdomains).
- An API key pair (
x-api-key/x-client-app-key) issued for your tenant. For the
shared dev environment, request the beta pair from your Inaya Labs contact; for a local stack, the pair is seeded by the platform migrations.
curl, or any HTTP client. Snippets also show Python and Node.
Concepts (only what this journey needs)
- Services are per-purpose microservices, each on its own port (local) or subdomain
(dev/prod). There is no single API gateway URL to memorize — you call the service you need.
- Health endpoints are unauthenticated. Every service exposes one so orchestrators
(and this guide) can probe liveness without credentials.
- Everything else is authenticated with a tenant key pair, and write endpoints also
require a JWT obtained through the Auth Service (see the Authentication guide).
Step 1 — Pick your base URL
Snippets use ${BASE_URL}. Map it to your environment:
| Environment | BASE_URL | Notes |
|---|---|---|
| Local dev stack | http://127.0.0.1:<service-port> | Per-service ports, e.g. Auth :40004, Memcache :40011. Always 127.0.0.1, not localhost (IPv6 refusal hangs some clients). |
| Shared dev | https://<service>-sandbox.inayalabs.com | e.g. https://auth-service-sandbox.inayalabs.com |
Step 2 — Prove a service is alive
Call an unauthenticated health endpoint. Auth Service:
curl -s "${BASE_URL}/v3/health"import os, urllib.request
base = os.environ["BASE_URL"]
print(urllib.request.urlopen(f"{base}/v3/health").read().decode())const base = process.env.BASE_URL;
const res = await fetch(`${base}/v3/health`);
console.log(await res.text());Expected response (the platform HealthInfo — minimal by design):
{ "status": "Up" }PITFALL
A 000/connection-refused almost always means one of: the service isn't running, you used localhost instead of 127.0.0.1 on the local stack, or you're hitting a dev subdomain without network access — not an auth problem.
Step 3 — Present your key pair
NOTE
Sandbox exception. Services running with INAYA_LABS_ENVIRONMENT=sandbox (the Playground stack) skip authentication entirely — any or no JWT and any or no tenant key pair are accepted, and requests run under a synthetic sandbox-user identity. The key pair below is only required outside the Sandbox environment.
All non-health endpoints require the tenant key pair as headers:
| Header | Value |
|---|---|
x-api-key | Your tenant API key |
x-client-app-key | Your client application key |
Keep them in your environment, never in source control:
export INAYA_API_KEY="…"
export INAYA_APP_KEY="…"Step 4 — Make your first authenticated call
List the federated sign-in methods the tenant supports — a safe, read-only first call:
curl -s -X POST "${BASE_URL}/v3/auth/login_methods" \
-H "Content-Type: application/json" \
-H "x-api-key: ${INAYA_API_KEY}" \
-H "x-client-app-key: ${INAYA_APP_KEY}" \
-d '{"locale": "en-US"}'import os, json, urllib.request
req = urllib.request.Request(
f"{os.environ['BASE_URL']}/v3/auth/login_methods",
data=json.dumps({"locale": "en-US"}).encode(),
headers={
"Content-Type": "application/json",
"x-api-key": os.environ["INAYA_API_KEY"],
"x-client-app-key": os.environ["INAYA_APP_KEY"],
},
)
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))const res = await fetch(`${process.env.BASE_URL}/v3/auth/login_methods`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.INAYA_API_KEY,
"x-client-app-key": process.env.INAYA_APP_KEY,
},
body: JSON.stringify({ locale: "en-US" }),
});
console.log(await res.json());Expected response — every method the tenant supports, plus the subset enabled for the request's region (contents vary by tenant and locale):
{ "all_methods": ["FederatedApple", "FederatedGoogle", "Passkey"], "regional_methods": ["FederatedApple"] }PITFALL
401 here means the key pair was rejected: wrong tenant, wrong header names, or a stale key. 415 means you forgot Content-Type: application/json — every POST body in the platform is JSON unless documented otherwise.
Full working example
A complete script that checks health, then lists login methods — save as first_call.sh and run with BASE_URL, INAYA_API_KEY, INAYA_APP_KEY set:
#!/usr/bin/env bash
set -euo pipefail
echo "1. Health:"
curl -sf "${BASE_URL}/v3/health" && echo
echo "2. Login methods:"
curl -sf -X POST "${BASE_URL}/v3/auth/login_methods" \
-H "Content-Type: application/json" \
-H "x-api-key: ${INAYA_API_KEY}" \
-H "x-client-app-key: ${INAYA_APP_KEY}" \
-d '{"locale": "en-US"}'
echoTry it live
Open the Playground → Users & Profile Matching → Users console — it signs in against the live Auth Service and exercises the same key-pair headers.
Copy agent prompt
You are integrating with the Inaya Labs platform. Environment: ${BASE_URL}
(local or dev per the mapping table in guide G-00). Credentials are in
INAYA_API_KEY / INAYA_APP_KEY env vars (x-api-key / x-client-app-key headers).
First verify ${BASE_URL}/v3/health returns 200, then call POST
/v3/auth/login_methods with body {"locale":"en-US"} and the key-pair headers,
and report the enabled login methods. Do not retry 4xx responses; only retry
connection failures, up to 3 times.API reference
Next journeys
- Authentication & sessions (G-01, Phase 1) — sign in, handle tokens, sign out.
- Errors, retries & idempotency (G-03, Phase 1) — what to do when calls fail.