# CAMARA Sandbox

A mock gateway for [CAMARA](https://camaraproject.org) telecom APIs: SIM swap,
device location, roaming, reachability and KYC match. It exists to show how an
HTTP API can be discovered and called by an autonomous agent: OAuth2
`client_credentials`, `_links` HATEOAS navigation, Events Query streaming and
`/.well-known/` discovery.

Auth with `sandbox` / `sandbox`. Every number and every result below is mock
data.

## Start here

| What | Where |
| --- | --- |
| Agent instructions, test numbers, request bodies | <https://camara.jaime.win/SKILL.md> |
| API catalog (RFC 9727) | <https://camara.jaime.win/.well-known/api-catalog?sandbox=true> |
| Capability manifest (ARD) | <https://camara.jaime.win/.well-known/ai-catalog.json> |
| Agent registration (auth.md) | <https://camara.jaime.win/auth.md> |
| MCP server card | <https://camara.jaime.win/.well-known/mcp/server-card.json> |
| A2A agent card | <https://camara.jaime.win/.well-known/agent-card.json> |
| Agent skills index | <https://camara.jaime.win/.well-known/agent-skills/index.json> |
| OpenID Connect discovery | <https://camara.jaime.win/.well-known/openid-configuration> |
| OAuth protected resource (RFC 9728) | <https://camara.jaime.win/.well-known/oauth-protected-resource> |
| OAuth authorization server (RFC 8414) | <https://camara.jaime.win/.well-known/oauth-authorization-server> |

## Get a token

```sh
curl -s https://camara.jaime.win/oauth2/token \
  -d grant_type=client_credentials -d client_id=sandbox -d client_secret=sandbox
```

The response carries the access token plus an `_links` map of every operation it
unlocks, so an agent can navigate from the token rather than from documentation.

## Live endpoints

| Operation | Path |
| --- | --- |
| SIM swap check | `POST /sim-swap/v1/check` |
| SIM swap date | `POST /sim-swap/v1/retrieve-date` |
| Location verification | `POST /device-location-verification/v1/verify` |
| Location retrieval | `POST /location-retrieval/v1/retrieve` |
| Number verification | `POST /number-verification/v1/verify` |
| Device phone number | `GET /number-verification/v1/device-phone-number` |
| Roaming status | `POST /device-roaming-status/v1/retrieve` |
| Reachability status | `POST /device-reachability-status/v1/retrieve` |
| KYC match | `POST /kyc-match/v1/match` |

## Example call

```sh
TOKEN=$(curl -s https://camara.jaime.win/oauth2/token \
  -d grant_type=client_credentials -d client_id=sandbox -d client_secret=sandbox \
  | python3 -c 'import sys,json;print(json.load(sys.stdin)["access_token"])')

curl -s https://camara.jaime.win/sim-swap/v1/check \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"phoneNumber":"+34600000001","maxAge":240}'
```

## Streaming subscriptions

The SIM swap, location retrieval, roaming and reachability resources also accept
`QUERY` with `Accept-Query: application/events+json`, per
`draft-gupta-httpapi-events-query`. Requests show up live at
<https://camara.jaime.win/eqp-log>.

## Errors

Failures are RFC 9457 `application/problem+json`, and each one names the next
useful step: a `401` points at the token endpoint and the protected resource
metadata, an unknown test number returns the list of numbers that do work.

---

Jaime Jiménez · <https://jaime.win> · source: <https://github.com/jaimejim>
