# Self-managed Intent Router API examples

```json metadata
{
  "schema_version": 2,
  "title": "Self-managed Intent Router API examples",
  "description": "Create a Router, mint an agent key, verify agent access, hand off to a developer, and rotate or revoke keys.",
  "categories": ["docs","operate","iris"],
  "tableOfContents": {"sections":[{"id":"set-connection-values","title":"Set connection values"},{"id":"create-a-router","title":"Create a Router"},{"id":"mint-an-agent-key","title":"Mint an agent key"},{"id":"verify-agent-access","title":"Verify agent access"},{"id":"hand-off-to-a-developer","title":"Hand off to a developer"},{"id":"rotate-or-revoke-agent-keys","title":"Rotate or revoke agent keys"}]}

,
  "codeExamples": [{"codetabsId":"iris_intent_router_service-stepmodels-list","difficulty":"beginner","id":"models-list","languages":[{"clientId":"iris-curl","clientName":"cURL (Iris)","id":"cURL (Iris)","langId":"bash","panelId":"panel_cURL (Iris)_iris_intent_router_service-stepmodels-list"},{"clientId":"iris-cli","clientName":"CLI (Iris)","id":"CLI (Iris)","langId":"bash","panelId":"panel_CLI (Iris)_iris_intent_router_service-stepmodels-list"}]},{"codetabsId":"iris_intent_router_service-steprouter-create","difficulty":"beginner","id":"router-create","languages":[{"clientId":"iris-curl","clientName":"cURL (Iris)","id":"cURL (Iris)","langId":"bash","panelId":"panel_cURL (Iris)_iris_intent_router_service-steprouter-create"},{"clientId":"iris-cli","clientName":"CLI (Iris)","id":"CLI (Iris)","langId":"bash","panelId":"panel_CLI (Iris)_iris_intent_router_service-steprouter-create"}]},{"codetabsId":"iris_intent_router_service-steprouter-wait","difficulty":"beginner","id":"router-wait","languages":[{"clientId":"iris-curl","clientName":"cURL (Iris)","id":"cURL (Iris)","langId":"bash","panelId":"panel_cURL (Iris)_iris_intent_router_service-steprouter-wait"},{"clientId":"iris-cli","clientName":"CLI (Iris)","id":"CLI (Iris)","langId":"bash","panelId":"panel_CLI (Iris)_iris_intent_router_service-steprouter-wait"}]}]
}
```

## Code examples

These examples connect to Iris services using SDKs or HTTP requests with curl. Follow one language throughout each walkthrough.


After you deploy Intent Router, developers still can't use it until a Router and an agent key exist. This page walks through that setup: you create a Router, issue an agent key for it, check that the key works, and give the connection values to a developer. The developer then continues with the [developer quickstart](https://redis.io/docs/latest/develop/ai/context-engine/intent-router/quickstart). The page also covers rotating and revoking agent keys after handoff.

Before you begin, [deploy the chart](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/deploy) and [load the administration tokens](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/authentication#load-the-administration-tokens).

## Set connection values

Forward the control plane, the data plane, and the Identity Service in separate terminals, as in [Deploy](https://redis.io/docs/latest/operate/iris/intent-router/self-managed/deploy#5-verify-pods-and-health), then export the connection values:

```bash
export IRIS_INTENT_ROUTER_SERVICE_URL='http://localhost:9400'
export IRIS_INTENT_ROUTER_URL='http://localhost:9401'
export IRIS_IDENTITY_URL='http://localhost:9200'
export IRIS_IDENTITY_TENANT='<tenant-id>'
umask 077
```

`IRIS_INTENT_ROUTER_SERVICE_TOKEN` holds the admin token and `IRIS_IDENTITY_TOKEN` holds the Identity Service control token. `IRIS_IDENTITY_TENANT` is the deployment's `tenantId`. For application deployment, use the endpoints your platform exposes.

## Create a Router

List the offered models, then create a Router with one of them and wait for it to be ready. See [Manage Routers](https://redis.io/docs/latest/develop/ai/context-engine/intent-router/manage-routers) for each step with Python, TypeScript, and the command-line interface (CLI).

**Available in:** cURL (Iris), CLI (Iris)

##### cURL (Iris)

```bash
SERVICE_API="${IRIS_INTENT_ROUTER_SERVICE_URL%/}/iris/v1/intent"
curl --fail-with-body --silent --show-error \
  "$SERVICE_API/models?purpose=EMBEDDING" \
  -H "Authorization: Bearer $IRIS_INTENT_ROUTER_SERVICE_TOKEN" > models.json
jq -c '.items[] | {provider, model, dimensions, authorization}' models.json
```

##### CLI (Iris)

```bash
iris --json intent-router service models --purpose embedding > models.json
jq -c '.items[] | {provider, model, dimensions, authorization}' models.json
```



**Available in:** cURL (Iris), CLI (Iris)

##### cURL (Iris)

```bash
curl --fail-with-body --silent --show-error \
  -X POST "$SERVICE_API/routers" \
  -H "Authorization: Bearer $IRIS_INTENT_ROUTER_SERVICE_TOKEN" \
  -H 'Content-Type: application/json' \
  --data "$(jq '{
    name: "support-router",
    description: "Routes support requests to tools and agents.",
    template: "AGENT",
    minScore: 0.7,
    vectorSpace: (.items[0] | {provider, model, dimensions})
  }' models.json)" > router.json
ROUTER_ID=$(jq -er .routerId router.json)
jq -c '{routerId, state, revision}' router.json
```

##### CLI (Iris)

```bash
iris intent-router service create --name support-router \
  --description "Routes support requests to tools and agents." \
  --template agent --min-score 0.7 \
  --provider "$(jq -er '.items[0].provider' models.json)" \
  --model "$(jq -er '.items[0].model' models.json)" \
  --dimensions "$(jq -er '.items[0].dimensions' models.json)" \
  --wait | tee router.env
ROUTER_ID=$(sed -n 's/^IRIS_INTENT_ROUTER_ID=//p' router.env)
```



**Available in:** cURL (Iris), CLI (Iris)

##### cURL (Iris)

```bash
until [ "$(curl --fail-with-body --silent --show-error \
  "$SERVICE_API/routers/$ROUTER_ID" \
  -H "Authorization: Bearer $IRIS_INTENT_ROUTER_SERVICE_TOKEN" | tee router.json | jq -r .state)" != "PROVISIONING" ]; do
  sleep 1
done
jq -c '{routerId, state, failureReason}' router.json
jq -e '.state == "READY"' router.json > /dev/null
```

##### CLI (Iris)

```bash
iris --json intent-router service show "$ROUTER_ID" > router.json
jq -c '{routerId, state, failureReason}' router.json
jq -e '.state == "READY"' router.json > /dev/null
```



The create step saves the new Router's ID in `ROUTER_ID`. With the CLI, `iris intent-router service create --wait --write-env .env` creates the Router, waits until it is `READY`, and also mints its agent key into `.env`, so you can skip the next section.

## Mint an agent key

Issue one key with a `write` grant on the Router. In a new shell, first set `ROUTER_ID` to the saved `routerId`.

```bash
: "${ROUTER_ID:?Set ROUTER_ID to the saved routerId}"
jq -n --arg tenant "$IRIS_IDENTITY_TENANT" --arg router "$ROUTER_ID" '{
  name: "support-app",
  grants: [
    {tenant: $tenant, product: "intent", resourceType: "intent-router", resourceId: $router, actions: ["write"]}
  ]
}' > agent-grant.json

curl --fail-with-body --silent --show-error \
  -X POST "$IRIS_IDENTITY_URL/v1/api-keys" \
  -H "Authorization: Bearer $IRIS_IDENTITY_TOKEN" \
  -H 'Content-Type: application/json' \
  --data-binary @agent-grant.json > agent-key.json

export IRIS_INTENT_ROUTER_ID="$ROUTER_ID"
export IRIS_INTENT_ROUTER_API_KEY="$(jq -er '.token' agent-key.json)"
KEY_ID="$(jq -er '.keyId' agent-key.json)"
jq '{keyId, createdAt}' agent-key.json
```

> [!WARNING]
> The response holds the key's `token` only once, when you mint or rotate the key. Store it in a secret manager and keep it out of source control.

Use `read` instead of `write` for an application that only classifies queries.

With the CLI, `iris intent-router service key "$ROUTER_ID" --role write --name support-app --write .env` mints the same key and writes the `IRIS_INTENT_ROUTER_*` values to `.env`. It reads `IRIS_IDENTITY_URL`, `IRIS_IDENTITY_TOKEN`, and `IRIS_IDENTITY_TENANT`.

## Verify agent access

Check that the key reaches the Router:

```bash
curl --fail-with-body --silent --show-error \
  "$IRIS_INTENT_ROUTER_URL/iris/data/v1/intent/routers/$IRIS_INTENT_ROUTER_ID/health" \
  -H "Authorization: Bearer $IRIS_INTENT_ROUTER_API_KEY" | jq .
```

## Hand off to a developer

Give the developer the data-plane endpoint as `IRIS_INTENT_ROUTER_URL`, the Router ID as `IRIS_INTENT_ROUTER_ID`, and the agent key as `IRIS_INTENT_ROUTER_API_KEY`. They continue with the [quickstart](https://redis.io/docs/latest/develop/ai/context-engine/intent-router/quickstart). Give platform teams who manage Routers the control-plane URL and admin token for [Manage Routers](https://redis.io/docs/latest/develop/ai/context-engine/intent-router/manage-routers). Remove `agent-key.json` and `agent-grant.json` after you save the token.

## Rotate or revoke agent keys

Rotating a key mints a replacement with a new `keyId` and token. The old key keeps working for a grace period, 3,600 seconds by default, so applications can switch over. Set `graceSeconds` to change it. Rotation returns the new token once:

```bash
curl --fail-with-body --silent --show-error \
  -X POST "$IRIS_IDENTITY_URL/v1/api-keys/$KEY_ID/rotate?graceSeconds=600" \
  -H "Authorization: Bearer $IRIS_IDENTITY_TOKEN" > agent-key.json
export IRIS_INTENT_ROUTER_API_KEY="$(jq -er '.token' agent-key.json)"
KEY_ID="$(jq -er '.keyId' agent-key.json)"
jq '{keyId, createdAt, oldExpiresAt}' agent-key.json
```

With the CLI, run `iris identity keys rotate "$KEY_ID" --grace 10m --write .env --env IRIS_INTENT_ROUTER_API_KEY`.

Revoke a key to stop it working:

```bash
curl --fail-with-body --silent --show-error \
  -X DELETE "$IRIS_IDENTITY_URL/v1/api-keys/$KEY_ID" \
  -H "Authorization: Bearer $IRIS_IDENTITY_TOKEN"
```

With the CLI, run `iris identity keys revoke "$KEY_ID"`. `iris identity keys list --resource-id "$ROUTER_ID"` lists a Router's keys.

A revoked key stops working within 300 seconds, the Identity Service's default cache lifetime. Revoke the keys for a Router before you delete it.

