Quickstart
This walkthrough goes from nothing to queryable impact data. All you need
is curl.
1. Get an API key
Section titled “1. Get an API key”Sign in at app.cast.commonapproach.org. If you are registering, choose Developer on the Start page; an existing account can switch under Settings → I use Lab as. The API item in the sidebar appears for the Developer role. Open it and create a key under the Settings tab.
Set up your shell for the rest of the walkthrough:
BASE=https://api.cast.commonapproach.orgKEY=your-api-key-here2. Create a namespace
Section titled “2. Create a namespace”A namespace is an isolated dataset within your tenant. Every data request names one explicitly — nothing is shared between namespaces.
curl -s -X POST $BASE/namespaces \ -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"namespace": "quickstart", "label": "Quickstart walkthrough"}'Namespace slugs are lowercase letters, digits, and hyphens
(^[a-z0-9][a-z0-9-]{0,62}$). Creation is idempotent. From here on, every
request carries both the X-API-Key and X-Namespace headers. Namespaces
can also be created in the console under API → Settings.
3. Load data
Section titled “3. Load data”Option A — upload a capsule (if you already have CIDS JSON-LD, e.g. an export from an aligned platform):
curl -X POST $BASE/capsules \ -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ -H "Content-Type: application/json" \ --data-binary @my-capsule.jsonld{"capsule_id": "9f3c1a7e5b2d4c88a1e6f04d7b92c3aa", "status": "pending"}Processing is asynchronous — poll with the capsule_id from the response
until the status is no longer pending (accepted, rejected, or
failed):
curl -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ $BASE/capsules/9f3c1a7e5b2d4c88a1e6f04d7b92c3aaA rejected capsule stores nothing and returns a plain-language validation report you can forward to whoever produced the file. See Capsules.
Option B — build it with CRUD calls. Every create supplies the
entity’s own URI — Lab never invents identifiers
(see Identifiers) — and returns an id you
use in the next call’s URL.
Create an organization:
curl -X POST $BASE/orgs \ -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ -H "Content-Type: application/json" \ -d '{"uri": "https://greenfield.example/org/ghc", "name": "Greenfield Housing Co-op"}'{"id": "ag7kailrb32j2djhdxlxv42vs4", "uri": "https://greenfield.example/org/ghc", …}Give it an outcome:
curl -X POST $BASE/orgs/ag7kailrb32j2djhdxlxv42vs4/outcomes \ -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ -H "Content-Type: application/json" \ -d '{"uri": "https://greenfield.example/outcome/housing-stability", "name": "Housing stability", "themes": ["https://metadata.un.org/sdg/1"]}'{"id": "qmcsw2qasowhmd6cs4nozkylsa", …}An indicator that measures the outcome:
curl -X POST $BASE/orgs/ag7kailrb32j2djhdxlxv42vs4/indicators \ -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ -H "Content-Type: application/json" \ -d '{"uri": "https://greenfield.example/indicator/tenant-retention", "name": "Tenant retention rate (%)", "unit": "%", "outcome_id": "qmcsw2qasowhmd6cs4nozkylsa"}'{"id": "mwv3xpkiyefhv26l3kdwolrzaa", …}And a report with a value:
curl -X POST $BASE/indicators/mwv3xpkiyefhv26l3kdwolrzaa/reports \ -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ -H "Content-Type: application/json" \ -d '{"uri": "https://greenfield.example/report/tenant-retention-2025", "value": 94, "unit": "%", "period_start": "2025-01-01", "period_end": "2025-12-31"}'Re-running any of these CRUD calls with the same URIs is a safe upsert —
re-POSTing a report URI with a corrected value replaces it. (Capsules
work differently: a corrected capsule is submitted with
?replaces={old capsule id}.)
4. Query
Section titled “4. Query”# every indicator report, denormalized (indicator, outcome, themes, org on each row)curl -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ "$BASE/rows/indicator-reports?limit=50"
# what themes exist, with report counts — feed for a filter pickercurl -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ $BASE/facets/themes
# filter: one theme, one year (period is an overlap filter)curl -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ "$BASE/rows/indicator-reports?theme=https%3A%2F%2Fmetadata.un.org%2Fsdg%2F1&period[from]=2025-01-01&period[to]=2025-12-31"
# one organization's full theory of change as a treecurl -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ $BASE/orgs/ag7kailrb32j2djhdxlxv42vs4/everything
# everything in the namespace as CIDS JSON-LD — the response is a short-lived# download URL, so fetch thatcurl -s -H "X-API-Key: $KEY" -H "X-Namespace: quickstart" \ $BASE/export | jq -r .url | xargs curl -sSee Querying for the full filter reference.
Where next
Section titled “Where next”- Identifiers — how entity identity works (required reading before a real integration).
- Capsules — validation rules, rollback, and modelling funder relationships.
- Errors & reference — every endpoint and the error contract.
- Console — manage keys and namespaces, try endpoints in the Playground, and inspect what you loaded.
