# Sources

## Introduction

A source is a database, MCP server, or API you add to swarmvia. Callers reach it
at the source's endpoint, with a hard concurrency limit in front of it. Each
source has an endpoint (`https://‹subdomain›.swarmvia.cloud`), allowed origins,
caller authentication, and concurrency settings.

A source's **backend** decides what sits behind that limit. The default is an
HTTPS origin, which swarmvia proxies to. A [database source](/docs/sources/database)
fronts a PostgreSQL or MySQL database instead, and answers SQL over HTTP on its
own hostname. Everything else — keys, concurrency, credentials, logs — is the
same either way. The backend is chosen when the source is created and cannot be
changed afterwards.

Create sources under **Sources** in the dashboard. Each source has tabs that match
this documentation:

| Tab | What it covers |
|-----|----------------|
| Overview | Live status and how the source is reached |
| [Concurrency](/docs/sources/concurrency) | Limit, queue, RPM, retries, response cache |
| [Access](/docs/sources/access) | Access keys, session tokens, origin verification, JWT, Cloudflare Access, IP policies |
| [Logs](/docs/sources/logs) | Access logs and tags |
| [Settings](/docs/sources/settings) | Origins, custody, name |
| [Database](/docs/sources/database) | Postgres or MySQL backend: connection, read role, query limits |

## Hostnames

| Host | Role |
|------|------|
| `‹source›.swarmvia.cloud` | Proxy traffic for that source |
| `api.swarmvia.cloud` | [Concurrency locks](/docs/api/locks) and [async job poll](/docs/sources/async) |

Reserved labels such as `api`, `edge`, `www`, `to`, and `fallback` cannot be
source subdomains.

## Calling the source

Proxy traffic goes to your source's endpoint. The path and query string are
forwarded to the selected origin after admission. All inbound `X-Swarmvia-*`
headers are stripped before the upstream request.

```bash
curl -sS "https://your-source.swarmvia.cloud/v1/records" \
  -H "X-Swarmvia-Key: $ACCESS_KEY"
```

## Request headers

| Header | Purpose |
|--------|---------|
| `X-Swarmvia-Key` | Access key (required when the source requires a key) |
| `Authorization` | Managed: may carry `Bearer` / `Swarmvia` access key. Pass-through: upstream credential |
| `X-Swarmvia-Origin` | Exact origin when the source has multiple origins |
| `X-Swarmvia-Cache-TTL` | Opt-in response cache TTL in seconds (max 300); GET/HEAD only |
| `X-Swarmvia-Tags` | Access-log tags (max 64 characters) |
| `X-Swarmvia-No-Queue` | Fail fast instead of queuing when set (not `0` / `false`) |
| `X-Swarmvia-Queue-Timeout-Ms` | Per-request queue wait budget in milliseconds |

The previous `X-Nthpool-*` names are still accepted on requests. Responses send both names.

JWT and Cloudflare Access headers are covered in
[Access](/docs/sources/access).

## Response headers

Successful (and many rejected) responses may include:

| Header | Meaning |
|--------|---------|
| `x-swarmvia-remaining-slots` | Free concurrency slots after this admission |
| `x-swarmvia-queue-depth` | Requests waiting in the source's queue |
| `x-swarmvia-queued-ms` | Time spent waiting for a concurrency slot (`0` if admitted immediately). Does not include network round-trip. |
| `x-swarmvia-total-ms` | swarmvia + queue wait + upstream |
| `x-swarmvia-effective-limit` | Current concurrency limit (fixed or learned) |
| `Retry-After` | Seconds to wait on a source `429` / `504` when applicable |

## Status codes from the source

These are returned by swarmvia **before or instead of** the upstream response:

| Status | Typical cause |
|--------|----------------|
| `400` | Invalid or missing origin selection |
| `401` | Missing, invalid, expired, or revoked key or session token; rejected JWT |
| `403` | IP policy rejection (blocked, or not allowed), or custom-hostname lock |
| `413` | Payload too large |
| `429` | Queue full, fail-fast (`X-Swarmvia-No-Queue`), or rate gate overloaded |
| `499` | Client cancelled while waiting or in flight |
| `501` | Source is not configured yet |
| `502` | Upstream error while proxying |
| `503` | Source suspended |
| `504` | Queue wait timeout or request/lease timeout |

Upstream status codes are passed through when the request was admitted and
fetched successfully (or failed at the origin).

## Next steps

- [Quickstart](/docs/quickstart)
- [Access](/docs/sources/access) (keys, session tokens, origin verification)
- [Concurrency](/docs/sources/concurrency)
- [Concurrency locks API](/docs/api/locks) (same concurrency limit, no proxying)
- [Credentials](/docs/credentials) (managed upstream secrets)
- [Determine a request came from the proxy](/docs/knowledge-base/origin-verification)
- [Admission errors](/docs/knowledge-base/admission-errors)
