multi-routerdocs

Routers

Last updated June 8, 2026

Overview

A Router is the unit you target from an inference request. Instead of calling a provider directly, you send a chat or messages request tomulti-router/<router> and the router decides which model serves it, using your own provider keys.

Routers belong to your organization and carry a unique id prefixed with rt_. You reference a router in the model field of a request by its id (multi-router/rt_8f3k2m9x4n1p) or by an alias's handle (multi-router/production).

Bring Your Own Key (BYOK)
A router routes to a provider using a provider key(llpk_…) you configure in the dashboard. Your keys are encrypted and stored in AWS Secrets Manager — Multi-Router never holds its own model credits.

Router Kinds

Every router is one of four kinds. The kind is fixed at creation and cannot be changed.

  • llm_router — routes to one provider + model with a provider key. The workhorse kind.
  • alias — a stable handle that points at another router. You choose its id; re-point it without changing callers.
  • fallback — an ordered list of member routers; tries each in turn until one succeeds.
  • weighted — splits traffic across member routers by weight.

Routers are created with PUT /v1/routers and an Idempotency-Keyheader (a server-minted rt_ id is returned for every kind except alias, whose id you supply).

Create an llm_routerbash
curl -X PUT https://api.multi-router.ai/v1/routers \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "llm_router",
    "name": "haiku-direct",
    "provider": "anthropic",
    "model": "claude-haiku-4-5",
    "provider_key_id": "llpk_klIwQ0DcMj",
    "settings": { "system_message_mode": "merge" }
  }'
Response 201json
{
  "organization_id": "org_B9a3tZ3da1",
  "router": {
    "id": "rt_EAMsQkYivY",
    "name": "haiku-direct",
    "kind": "llm_router",
    "provider": "anthropic",
    "model": "claude-haiku-4-5",
    "provider_key_id": "llpk_klIwQ0DcMj",
    "target_id": null,
    "members": null,
    "settings": {
      "system_message_mode": "merge"
    },
    "prompt_binding": null,
    "enabled": true,
    "created_at": "2026-06-08T17:47:43Z",
    "updated_at": "2026-06-08T17:47:43Z"
  }
}

An alias supplies its own id and a target_id:

Create an aliasbash
curl -X PUT https://api.multi-router.ai/v1/routers \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "kind": "alias", "id": "production", "target_id": "rt_EAMsQkYivY" }'

A fallback or weighted router lists members by id. Weighted members carry a positive weight; fallback members omit it (order is the priority):

Weighted router bodyjson
{
  "kind": "weighted",
  "name": "canary",
  "members": [
    {
      "id": "rt_EAMsQkYivY",
      "weight": 90
    },
    {
      "id": "rt_Q-Jc_RTpSm",
      "weight": 10
    }
  ]
}

Prompt Bindings

An llm_router can bind a prompt — a reusable system prompt that composes with each request. Set prompt_binding on create or edit. The binding references an inline prompt (prompt_id, ip_…) or a GitHub-sourced one (prompt_repo_id + file_path).

rev_mode is latest (always the newest revision) orpinned (a fixed pinned_value — a revision number for inline, a commit SHA for GitHub). settings.system_message_mode controls how the bound prompt composes with the caller's own system message: merge, override, or fallback.

An llm_router body with a pinned GitHub bindingjson
{
  "kind": "llm_router",
  "name": "support-bot",
  "provider": "anthropic",
  "model": "claude-haiku-4-5",
  "provider_key_id": "llpk_klIwQ0DcMj",
  "settings": {
    "system_message_mode": "override"
  },
  "prompt_binding": {
    "source": "github",
    "prompt_repo_id": "pr_de_heO_cUR",
    "file_path": "prompts/support.md",
    "rev_mode": "pinned",
    "pinned_value": "fb76a9bee2828c7e97dd9b0a367fbd6757dd9fdc"
  }
}
Validated at write time
The referenced prompt must exist in your organization, and a pinned binding's revision (inline) or commit (GitHub) is verified before the router is saved — an unresolvable pin is rejected with a 400.

Lifecycle

A router is enabled (serving) or disabled (not serving). Toggle with the action endpoints; deleting requires the router be disabled first and have no aliases pointing at it.

enabled→ /disable →disabled→ /enable →enabled|disabled→ DELETE →removed

Deleting an enabled router returns 409 router_enabled; deleting one with aliases still pointing at it returns 409 has_dependent_aliases. Re-point or remove those aliases first.

Prompts

Last updated June 8, 2026

Overview

A Prompt is a reusable template you bind to a router (see prompt_binding). Prompts are text (a single string) or chat (an array of {role, content} messages), and either bodies may contain {{variables}}.

There are two sources, distinguished by id prefix:

  • Inline (ip_…) — authored through the API or dashboard, edited in place, fully version-tracked.
  • GitHub (pf_…) — a file in a connected repo, synced automatically and read-only through the API (you edit it with a commit).

Both appear together in GET /v1/prompts; filter with ?source=inline or ?source=github.

Inline Prompts

Create an inline prompt with PUT /v1/prompts. Editing it (POST /v1/prompts/{id}) appends a new revision and bumpscurrent_rev; past revisions are retrievable, so a binding can pin to an exact one.

A chat prompt body (with a variable)json
{
  "type": "chat",
  "name": "greeting",
  "body": [
    {
      "role": "system",
      "content": "You are a concise assistant. Greet {{name}} warmly."
    }
  ]
}

Variables are filled per request via the prompt_variables field on/v1/chat/completions. A bound prompt with an unfilled required variable returns a400 missing_prompt_variables.

GitHub Prompt Sources

GitHub prompts live in a repo you connect once. The flow:

  • Connect an account — install the Multi-Router GitHub App on an org or personal account and claim it (a one-time dashboard step). Read or remove connections via /v1/github/connections.
  • Connect a repoPOST /v1/prompt-repos with a repo_full_name, branch, and the file_paths to track. Each tracked .md/.json file becomes a pf_ prompt.
  • Stay in sync — a push to the tracked branch re-syncs the file content automatically via webhook. No polling.

A connected repo carries an pr_ id; each of its tracked files reports itspf_ prompt_id, which you read with get_promptor bind to a router exactly like an inline ip_.

Pin to a commit
Bind a GitHub prompt with rev_mode: "pinned" and a commit SHA inpinned_value to freeze the exact wording a router serves, independent of later pushes.

API Reference

Last updated June 8, 2026

Authentication

Every request carries a Bearer token in the Authorization header. Tokens are prefixedsk-mr- and are scoped to a single organization — the token decides the org, and every response echoes its organization_id. Create and reveal tokens in the dashboard.

Authenticated requestbash
curl https://api.multi-router.ai/v1/models \
  -H "Authorization: Bearer sk-mr-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

To route an inference request through a router, put multi-router/<router> in themodel field (an rt_ id or an alias handle). There is no routing header — the model field selects the router. You can also bypass routers and call a provider directly with <provider>/<model>.

Chat Completions

OpenAI-compatible. Point an OpenAI SDK at https://api.multi-router.ai/v1, set themodel to a router or a provider/model, and use it unchanged. Supports synchronous JSON and SSE streaming.

POST/v1/chat/completionsCreate a chat completion
Requestbash
curl -X POST https://api.multi-router.ai/v1/chat/completions \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "multi-router/production",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "What is multi-router?"}
    ],
    "max_tokens": 1024
  }'
Response 200json
{
  "id": "chatcmpl-9f2k3m8x4n1pQ7",
  "object": "chat.completion",
  "created": 1773173342,
  "model": "multi-router/production",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Multi-Router is an LLM routing platform..."
      },
      "finish_reason": "stop",
      "logprobs": null
    }
  ],
  "usage": {
    "prompt_tokens": 24,
    "completion_tokens": 150,
    "total_tokens": 174
  }
}
Echoed model + diagnostic headers
The model in the response echoes what you sent. The model that actually served the request is returned in the x-mr-upstream-model response header (alongsidex-mr-provider and x-mr-attempts). The response body has no cost field; per-request cost is recorded server-side.

The model field

The model field accepts three forms:

ParameterTypeDescription
multi-router/<id-or-alias>routerRoute through a router by its rt_ id or an alias handle.
<provider>/<model>directCall a provider directly, e.g. anthropic/claude-haiku-4-5 or openai/gpt-4o.
<model>bareA bare name is matched against your routers first, then inferred.

Beyond the standard OpenAI fields, the API honors stream (SSE), tools /tool_choice (function calling), image content parts (vision),response_format (JSON / JSON-schema structured outputs), reasoning_effort, and a Multi-Router extension prompt_variables (an object of strings that fills{{variables}} in a router's bound prompt). n must be 1.

Streamingbash
curl -N -X POST https://api.multi-router.ai/v1/chat/completions \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "model": "multi-router/production", "stream": true,
        "messages": [{"role":"user","content":"hi"}] }'
# → text/event-stream: data: {chat.completion.chunk} ... data: [DONE]

Supported Providers

Direct provider/model calls (and router targets) support these providers:

Anthropicanthropic/
OpenAIopenai/
Google Geminigemini/
Coherecohere/
AWS Bedrockbedrock/

Messages

Anthropic-compatible. Point an Anthropic SDK at https://api.multi-router.ai/v1 and use the same model grammar. Supports streaming. max_tokens is required.

POST/v1/messagesCreate a message
Requestbash
curl -X POST https://api.multi-router.ai/v1/messages \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "multi-router/production",
    "max_tokens": 1024,
    "system": "You are a helpful assistant.",
    "messages": [ {"role": "user", "content": "What is multi-router?"} ]
  }'
Response 200json
{
  "id": "msg_01Xp4kQ7n2m8",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Multi-Router is an LLM routing platform..."
    }
  ],
  "model": "multi-router/production",
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 24,
    "output_tokens": 150
  }
}
Error shape
Errors use the Anthropic envelope: { "type": "error", "error": { "type": "...", "message": "..." } }. The Messages API has no prompt_variables field, so a router whose bound prompt requires a variable returns a 400.

Models

Lists the chat models available to your organization — filtered to providers you hold a key for. Requires authentication. The shape is OpenAI-compatible.

GET/v1/modelsList available models
Requestbash
curl https://api.multi-router.ai/v1/models \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "object": "list",
  "data": [
    {
      "id": "claude-haiku-4-5",
      "object": "model",
      "created": 1773000000,
      "owned_by": "anthropic"
    },
    {
      "id": "gpt-4o",
      "object": "model",
      "created": 1773000000,
      "owned_by": "openai"
    }
  ]
}

Routers

Manage routers. Single-resource responses wrap the router under router; the list wraps an array under routers. Both carry a top-level organization_id. See Routers for the model.

PUT/v1/routersCreate a router

Creates a router (idempotent — send an Idempotency-Key header). The body's kind selects the shape; see Router Kinds. Returns 201 with the created router and a Location header.

Requestbash
curl -X PUT https://api.multi-router.ai/v1/routers \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "llm_router",
    "name": "haiku-direct",
    "provider": "anthropic",
    "model": "claude-haiku-4-5",
    "provider_key_id": "llpk_klIwQ0DcMj",
    "settings": { "system_message_mode": "merge" }
  }'
Response 201json
{
  "organization_id": "org_B9a3tZ3da1",
  "router": {
    "id": "rt_EAMsQkYivY",
    "name": "haiku-direct",
    "kind": "llm_router",
    "provider": "anthropic",
    "model": "claude-haiku-4-5",
    "provider_key_id": "llpk_klIwQ0DcMj",
    "target_id": null,
    "members": null,
    "settings": {
      "system_message_mode": "merge"
    },
    "prompt_binding": null,
    "enabled": true,
    "created_at": "2026-06-08T17:47:43Z",
    "updated_at": "2026-06-08T17:47:43Z"
  }
}
GET/v1/routersList routers

Cursor-paginated. Optional ?kind=llm_router|alias|fallback|weighted, ?limit= (1–200, default 50), and ?cursor= from a prior response's next_cursor. Page until next_cursor is null.

Requestbash
curl "https://api.multi-router.ai/v1/routers?kind=llm_router&limit=20" \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "routers": [
    {
      "id": "rt_EAMsQkYivY",
      "name": "haiku-direct",
      "kind": "llm_router",
      "provider": "anthropic",
      "model": "claude-haiku-4-5",
      "provider_key_id": "llpk_klIwQ0DcMj",
      "settings": {
        "system_message_mode": "merge"
      },
      "prompt_binding": null,
      "enabled": true,
      "created_at": "2026-06-08T17:47:43Z",
      "updated_at": "2026-06-08T17:47:43Z"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
GET/v1/routers/:idGet a router

Returns one router by rt_ id or alias handle. 404 if it isn't in your org.

Requestbash
curl https://api.multi-router.ai/v1/routers/production \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "router": {
    "id": "production",
    "name": "production",
    "kind": "alias",
    "provider": null,
    "model": null,
    "provider_key_id": null,
    "target_id": "rt_EAMsQkYivY",
    "members": null,
    "settings": {
      "system_message_mode": "merge"
    },
    "prompt_binding": null,
    "enabled": true,
    "created_at": "2026-06-08T17:47:52Z",
    "updated_at": "2026-06-08T17:47:52Z"
  }
}
POST/v1/routers/:idEdit a router

A full-document replace — send the complete router again (id and kind are immutable). Omitted optional fields are cleared, including prompt_binding, so read-modify-write to preserve them. Returns the updated router.

Requestbash
curl -X POST https://api.multi-router.ai/v1/routers/rt_EAMsQkYivY \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "llm_router",
    "name": "haiku-direct",
    "provider": "anthropic",
    "model": "claude-haiku-4-5",
    "provider_key_id": "llpk_klIwQ0DcMj",
    "settings": { "system_message_mode": "override" }
  }'
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "router": {
    "id": "rt_EAMsQkYivY",
    "kind": "llm_router",
    "settings": {
      "system_message_mode": "override"
    },
    "...": "..."
  }
}
POST/v1/routers/:id/enableEnable a router

Resumes serving. Returns the updated router with enabled: true.

Requestbash
curl -X POST https://api.multi-router.ai/v1/routers/rt_EAMsQkYivY/enable \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "router": {
    "id": "rt_EAMsQkYivY",
    "enabled": true,
    "...": "..."
  }
}
POST/v1/routers/:id/disableDisable a router

Stops serving (not deleted). A router must be disabled before it can be deleted. Returns the updated router with enabled: false.

Requestbash
curl -X POST https://api.multi-router.ai/v1/routers/rt_EAMsQkYivY/disable \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "router": {
    "id": "rt_EAMsQkYivY",
    "enabled": false,
    "...": "..."
  }
}
DELETE/v1/routers/:idDelete a router

Permanently deletes a router. It must be disabled first (409 router_enabled) and have no aliases targeting it (409 has_dependent_aliases).

Requestbash
curl -X DELETE https://api.multi-router.ai/v1/routers/rt_EAMsQkYivY \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "id": "rt_EAMsQkYivY",
  "object": "router",
  "deleted": true
}

Prompts

Create, read, and version text/chat prompts. Create/edit/delete apply to inline (ip_) prompts only — GitHub (pf_) prompts are read-only here. Single responses wrap the resource under prompt; the list under prompts (summaries, no body).

PUT/v1/promptsCreate an inline prompt

Idempotent (Idempotency-Key header). Body: { type, name, body }body is a string for type:"text", an array of {role, content} for type:"chat". Returns 201.

Requestbash
curl -X PUT https://api.multi-router.ai/v1/prompts \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"type":"text","name":"greeting","body":"Greet {{name}} warmly."}'
Response 201json
{
  "organization_id": "org_B9a3tZ3da1",
  "prompt": {
    "id": "ip_2_S2YkmuHr",
    "source": "inline",
    "name": "greeting",
    "type": "text",
    "variables": [
      "name"
    ],
    "current_rev": "1",
    "body": "Greet {{name}} warmly.",
    "created_at": "2026-06-08T18:20:41Z",
    "updated_at": "2026-06-08T18:20:41Z"
  }
}
GET/v1/promptsList prompts

Inline + GitHub merged, cursor-paginated. Filters: ?source=inline|github, ?type=text|chat, ?prompt_repo_id=pr_…, ?limit=, ?cursor=. List items are summaries — no body or variables.

Requestbash
curl "https://api.multi-router.ai/v1/prompts?source=inline&limit=20" \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "prompts": [
    {
      "id": "ip_2_S2YkmuHr",
      "source": "inline",
      "name": "greeting",
      "type": "text",
      "current_rev": "1"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
GET/v1/prompts/:idGet a prompt

Returns the prompt with its full body and variables. Add ?rev= for a past revision (a number for inline, a commit SHA for GitHub). A pf_ id returns a github-sourced prompt with a github block.

Requestbash
curl https://api.multi-router.ai/v1/prompts/ip_2_S2YkmuHr \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "prompt": {
    "id": "ip_2_S2YkmuHr",
    "source": "inline",
    "name": "greeting",
    "type": "text",
    "variables": [
      "name"
    ],
    "current_rev": "1",
    "body": "Greet {{name}} warmly.",
    "created_at": "2026-06-08T18:20:41Z",
    "updated_at": "2026-06-08T18:20:41Z"
  }
}
POST/v1/prompts/:idEdit an inline prompt

Full replace (id and type immutable). A changed body appends a new revision and bumps current_rev. Returns the updated prompt.

Requestbash
curl -X POST https://api.multi-router.ai/v1/prompts/ip_2_S2YkmuHr \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"text","name":"greeting","body":"Hello {{name}}!"}'
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "prompt": {
    "id": "ip_2_S2YkmuHr",
    "type": "text",
    "current_rev": "2",
    "body": "Hello {{name}}!",
    "...": "..."
  }
}
DELETE/v1/prompts/:idDelete an inline prompt

Deletes the prompt and all its revisions.

Requestbash
curl -X DELETE https://api.multi-router.ai/v1/prompts/ip_2_S2YkmuHr \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "id": "ip_2_S2YkmuHr",
  "object": "prompt",
  "deleted": true
}
GET/v1/prompts/:id/revisionsList revisions

Revision history, newest first (inline: local revisions; GitHub: commit history for the file). Summaries only — fetch a body with GET /v1/prompts/:id/revisions/:rev.

Requestbash
curl https://api.multi-router.ai/v1/prompts/ip_2_S2YkmuHr/revisions \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "prompt_id": "ip_2_S2YkmuHr",
  "source": "inline",
  "revisions": [
    {
      "rev": "2",
      "title": "greeting",
      "created_at": "2026-06-08T19:02:00Z"
    },
    {
      "rev": "1",
      "title": "greeting",
      "created_at": "2026-06-08T18:20:41Z"
    }
  ]
}

GitHub Prompt Sources

Read GitHub connections and manage the repos you track prompts from. Connecting a GitHub account is a one-time dashboard step (install + claim the app); everything else is API-driven. See GitHub Prompt Sources for the model.

GET/v1/github/connectionsList connected accounts

Returns the GitHub accounts (orgs or personal accounts) connected to your org.

Requestbash
curl https://api.multi-router.ai/v1/github/connections \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "connections": [
    {
      "login": "multi-router",
      "installation_id": "131159071",
      "connected_at": "2026-05-28T22:36:41Z"
    }
  ]
}
DELETE/v1/github/connections/:loginDisconnect an account

Removes a connection by its login. Prompt-repos pointed at it remain but stop syncing.

Requestbash
curl -X DELETE https://api.multi-router.ai/v1/github/connections/multi-router \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "login": "multi-router",
  "object": "github_connection",
  "deleted": true
}
POST/v1/prompt-reposConnect a repo

Connects repo_full_name + branch and tracks file_paths (each .md/.json file becomes a pf_ prompt). The owner account must be connected first. (org, repo, branch) is unique — a duplicate is a 409 prompt_repo_exists.

Requestbash
curl -X POST https://api.multi-router.ai/v1/prompt-repos \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "prompts",
    "repo_full_name": "acme/prompts",
    "branch": "main",
    "file_paths": ["prompts/support.md"]
  }'
Response 201json
{
  "organization_id": "org_B9a3tZ3da1",
  "prompt_repo": {
    "id": "pr_de_heO_cUR",
    "name": "prompts",
    "repo_full_name": "acme/prompts",
    "branch": "main",
    "status": "synced",
    "last_synced_at": "2026-06-08T19:48:13Z",
    "created_at": "2026-06-08T19:48:13Z",
    "updated_at": "2026-06-08T19:48:13Z"
  },
  "files": [
    {
      "prompt_id": "pf_cHJfZGVfaGVPX2NVUi9zdXBwb3J0Lm1k",
      "file_path": "prompts/support.md",
      "status": "synced",
      "current_sha": "fb76a9b...",
      "error_message": "",
      "last_synced_at": "2026-06-08T19:48:13Z"
    }
  ]
}
GET/v1/prompt-reposList connected repos

Returns the connected repos (prompt sources) for your org.

Requestbash
curl https://api.multi-router.ai/v1/prompt-repos \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "prompt_repos": [
    {
      "id": "pr_de_heO_cUR",
      "name": "prompts",
      "repo_full_name": "acme/prompts",
      "branch": "main",
      "status": "synced",
      "last_synced_at": "2026-06-08T19:48:13Z",
      "created_at": "2026-06-08T19:48:13Z",
      "updated_at": "2026-06-08T19:48:13Z"
    }
  ]
}
GET/v1/prompt-repos/:idGet a repo + its files

Returns the repo and its tracked files; each file carries its pf_ prompt_id (read it with GET /v1/prompts/:id or bind it to a router).

Requestbash
curl https://api.multi-router.ai/v1/prompt-repos/pr_de_heO_cUR \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "prompt_repo": {
    "id": "pr_de_heO_cUR",
    "repo_full_name": "acme/prompts",
    "branch": "main",
    "status": "synced",
    "...": "..."
  },
  "files": [
    {
      "prompt_id": "pf_cHJfZGVf...",
      "file_path": "prompts/support.md",
      "status": "synced",
      "current_sha": "fb76a9b...",
      "error_message": "",
      "last_synced_at": "2026-06-08T19:48:13Z"
    }
  ]
}
POST/v1/prompt-repos/:id/filesTrack more files

Tracks additional file_paths on a connected repo and runs an initial sync. Re-adding a tracked path forces a re-sync. Returns the repo + the full file list.

Requestbash
curl -X POST https://api.multi-router.ai/v1/prompt-repos/pr_de_heO_cUR/files \
  -H "Authorization: Bearer $MR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "file_paths": ["prompts/triage.json"] }'
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "prompt_repo": {
    "id": "pr_de_heO_cUR",
    "...": "..."
  },
  "files": [
    {
      "prompt_id": "pf_cHJfZGVf...",
      "file_path": "prompts/support.md",
      "status": "synced",
      "...": "..."
    },
    {
      "prompt_id": "pf_cHJfdHJp...",
      "file_path": "prompts/triage.json",
      "status": "synced",
      "...": "..."
    }
  ]
}
DELETE/v1/prompt-repos/:id/files/:promptIdUntrack a file

Stops tracking one file by its pf_ prompt id; its GitHub prompt disappears. The repo and other files stay.

Requestbash
curl -X DELETE \
  https://api.multi-router.ai/v1/prompt-repos/pr_de_heO_cUR/files/pf_cHJfdHJp... \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "prompt_repo_id": "pr_de_heO_cUR",
  "prompt_id": "pf_cHJfdHJp...",
  "file_path": "prompts/triage.json",
  "object": "prompt_file",
  "deleted": true
}
DELETE/v1/prompt-repos/:idDisconnect a repo

Disconnects the repo and deletes all its tracked files (their pf_ prompts disappear).

Requestbash
curl -X DELETE https://api.multi-router.ai/v1/prompt-repos/pr_de_heO_cUR \
  -H "Authorization: Bearer $MR_API_KEY"
Response 200json
{
  "organization_id": "org_B9a3tZ3da1",
  "id": "pr_de_heO_cUR",
  "object": "prompt_repo",
  "deleted": true,
  "files_deleted": 2
}
Was this helpful?