Skip to main content
Prefer an API client to curl? Import the entire Phosra API into Postman or Insomnia in under a minute. The collection’s structure is generated from the canonical OpenAPI 3.1 spec, with curated example bodies layered on top, and comes pre-wired to the hosted sandbox — every request already points at {{baseUrl}} and authenticates with a single {{apiKey}} variable. Import it, drop in your key, and press Send.

Download collection

phosra-api.postman_collection.json — Postman Collection v2.1, 93 requests in 20 folders. Works in Postman and Insomnia.

Download sandbox environment

phosra-sandbox.postman_environment.json — sets baseUrl to the live sandbox and gives you an apiKey slot to fill in.
Both files are checked into the docs repo under docs/api/tools/. The request/folder structure is regenerated from the spec whenever it changes; the example bodies are curated by hand so they stay realistic rather than reverting to schema stubs.

What’s inside

The collection mirrors the API reference one-to-one:

93 requests, 20 folders

Auth, Families, Children, Policies, Rules, Enforcement, Platforms, Compliance, Webhooks, Standards, Ratings, Device Sync, and more — one folder per tag.

Pre-wired auth

Collection-level Bearer auth sends Authorization: Bearer {{apiKey}} on every request. Public reads (platforms, ratings, standards) work even before you set a key.

Example bodies filled in

Every write request that carries a body ships with a realistic, curated one — a single coherent “Rivera Household” family, real OCSS rule categories, and config shapes that match the API reference (time_daily_limit → {"daily_minutes": 120}, not a guessed field). No "string" placeholders; the create/update/enforce bodies run against the sandbox as-is. Action routes that take no body (activate, pause, retry, trigger) are correctly left empty.

Sandbox-first

{{baseUrl}} defaults to https://phosra-api-sandbox-production.up.railway.app/api/v1. Nothing you send can touch a production family.

Import into Postman

1

Download both files

Grab the collection and the sandbox environment using the buttons above.
2

Import them

In Postman, click Import (top-left) and drag both .json files in — or paste the file URLs into the Import → Link box. Postman detects the OpenAPI-derived collection and the environment automatically.
3

Select the environment

In the environment dropdown (top-right), choose Phosra Sandbox. baseUrl is already set to the live sandbox.
4

Add your key (optional for public reads)

Open the Phosra Sandbox environment, set apiKey to your phosra_test_… key, and save. Get one from Create your account. Public endpoints — Platforms, Ratings, Standards — return 200 without a key.
5

Send a request

Open Platforms → List all platforms and press Send. You should get a 200 with the seeded platform catalog. You are now talking to the live sandbox.

Import into Insomnia

Insomnia reads Postman v2.1 collections natively:
1

Import the collection

In Insomnia, open Application menu → Import, choose From File, and select phosra-api.postman_collection.json. Insomnia maps the 20 folders to request groups.
2

Set the base environment

Open Manage Environments and add:
{
  "baseUrl": "https://phosra-api-sandbox-production.up.railway.app/api/v1",
  "apiKey": "phosra_test_your_key_here"
}
The imported requests already reference {{ baseUrl }} and {{ apiKey }}.
3

Send

Pick any request and hit Send. Public reads work immediately; authenticated routes use your apiKey.

Verify it works

The first request most people run is Platforms → List all platforms. Resolved against the sandbox environment, it is exactly this call — copy-paste it to confirm the same 200 you’ll see in Postman:
curl -s "https://phosra-api-sandbox-production.up.railway.app/api/v1/platforms"
Real response from the live sandbox (HTTP 200, ~220 ms), trimmed to the first entry:
[
  {
    "id": "fire_tablet",
    "name": "Amazon Fire Tablet",
    "category": "device",
    "tier": "pending",
    "enabled": true
  }
  // … 22 platforms total
]
That is the same endpoint, base URL, and response the collection produces on Send — no mocks, no key required.

Environment variables

Two variables control where you send and how you authenticate:
VariableDefaultWhat it’s for
baseUrlhttps://phosra-api-sandbox-production.up.railway.app/api/v1The hosted sandbox root. Swap for https://prodapi.phosra.com/api/v1 when you go live.
apiKeyphosra_test_REPLACE_MEYour developer key. Sent as Authorization: Bearer {{apiKey}} on every authenticated request. Marked secret so it never syncs to a shared workspace. In the sandbox, the family/child/policy resources you create yourself are readable without a key — so most of the collection runs before you paste one in.
To move to production, duplicate the environment, set baseUrl to https://prodapi.phosra.com/api/v1, and use a phosra_live_… key. Every request shape is identical — only these two variables change.

Resource IDs — defined, not left blank

Every path and body that needs an id (/families/:familyID, {"family_id": "…"}, and so on) reads from a named collection variable — never a hand-copied UUID buried in a URL. The collection ships with all of them defined, so nothing resolves to a dangling {{familyId}} on import:
VariableSeeded withHow it gets a live value
standardId33e8b8cf-… — the real Four Norms community standardWorks immediately: GET /standards and GET /standards/four-norms return it with no setup.
familyIdthe shared sandbox demo familyOverwritten the moment you run Setup → One-step onboarding or Create a family.
childIddemo child MiaOverwritten by One-step onboarding or Add child to family.
policyIdMia’s demo policyOverwritten by One-step onboarding or Create policy for child.
ruleId, webhookId, sourceId, linkId, deviceId, jobId, memberId, feedbackId, ratingIdemptyCaptured automatically by the matching Create request (see below).
userIdemptyThe one id you bring yourself — a real WorkOS user id you want to add as a family member.
The familyId / childId / policyId defaults point at the shared demo family (Mia, Leo, Ava). Those rows are read-scoped to the guided walkthrough, so a GET against them from your own session returns 403 not a member of this family. That is expected — run Setup → One-step onboarding first (next section) and every id switches to a resource your session owns.

Path ids on public reads are pre-bound to real sandbox values

A handful of requests take a fixed, keyless identifier in the URL rather than a captured variable — the public catalog reads (Platforms, Standards, Ratings, Providers). Instead of the generator’s :platformID = "string" placeholder (which 404s on Send), every one of these is bound to a real value that resolves against the live sandbox immediately, no key and no setup:
RequestPath bindingResolves to
Platforms → Get platform detailsplatformID = appleGET /platforms/apple200
Platforms → Get OAuth authorization URLplatformID = microsoft200 — an OAuth-capable platform (device platforms like apple return 400 platform does not support OAuth)
Platforms → Handle OAuth callbackplatformID = microsoft200 — but supply a real code from the authorize step; the seeded code is a labeled placeholder
Providers → Get provider connect configdid = did:ocss:looplineGET /providers/did:ocss:loopline/connect200
Standards → Get a community standard by slugslug = four-normsGET /standards/four-norms200
Ratings → Get ratings for a specific rating systemsystemID = esrbGET /ratings/systems/esrb200
Ratings → Get content descriptors for a rating systemsystemID = esrb200
Device Sync → Get platform-specific identifier mappingsplatformID = appleGET /platform-mappings/apple200
Sources → Get guided stepscategory = web_filtering200 once {{sourceId}} is captured — connect a guided-tier source first (its path-var note explains this)
The only path binding that still needs a step first is Get guided steps: its category is now a real OCSS rule-category slug, but the request also reads {{sourceId}}, which stays empty until you connect a source. That dependency is spelled out on the request’s sourceID path-variable description — it is a labeled prerequisite, not a silent 404.

Run it top to bottom — IDs chain themselves

The Create requests carry a Postman test script that saves the new resource’s id straight into the collection variable the later requests read. Send them in order and you never paste a UUID:
1

Setup → One-step onboarding

POST /setup/quick returns a family, child, policy, and starter rules in one call. Its test script sets familyId, childId, policyId, and ruleId for you.
2

Anything that reads them

Get family, List children, Get policy, Create rule, Connect a webhook … all resolve against the ids the previous step captured. Create webhook / source / device / platform likewise write webhookId / sourceId / deviceId / linkId for their follow-up reads.
The capture scripts are plain pm.collectionVariables.set(...) calls — inspect them on any Create request under the Scripts → Post-response tab. This full chain is proven against the live sandbox:
BASE=https://phosra-api-sandbox-production.up.railway.app/api/v1

# 1. One-step onboarding → real family + child + policy ids
curl -s -X POST "$BASE/setup/quick" -H 'Content-Type: application/json' \
  -d '{"family_name":"Rivera Household","child_name":"Robin","birth_date":"2014-03-02"}'
# → 201 {"family":{"id":"a67a318c-…"},"child":{"id":"9a6782a2-…"},"policy":{"id":"ececceac-…"}, …}

# 2. GET the family the step above created (the id the test script captured)
curl -s "$BASE/families/a67a318c-f621-47a4-8ec9-e359db814b56"
# → 200 {"id":"a67a318c-…","name":"Rivera Household", …}

# standardId works with zero setup:
curl -s "$BASE/standards/four-norms"
# → 200 {"id":"33e8b8cf-1453-405a-8493-8fe76264623a","slug":"four-norms","name":"Four Norms", …}

Run in Postman

A one-click Run in Postman button requires the collection to be published to a public Postman workspace, which Phosra has not done yet — so rather than ship a button that 404s, we ship the collection file itself. The Import → Link flow above (paste the collection URL) is the equivalent one-step import and always tracks the checked-in file.

Keep it fresh

The collection’s structure is derived from docs/api/openapi.yaml — the same spec that powers the reference and the inline Try it runner — so the endpoints, folders, and auth stay in lock-step with the live API. When the spec version bumps, re-download the checked-in files. You can also regenerate the skeleton locally from the published spec (the CLI reads a local file, so fetch it first). Note the raw output ships schema-stub bodies ("name": "<string>"); the checked-in collection replaces those with the curated example bodies described above, so treat a fresh regen as a starting point, not a drop-in replacement:
curl -s https://phosra-api-sandbox-production.up.railway.app/openapi.json -o openapi.json

npx openapi-to-postmanv2 \
  -s openapi.json \
  -o phosra-api.postman_collection.json \
  -p -O folderStrategy=Tags

Next steps

API playground

Run keyless requests without leaving the docs — inline Try it on every reference page.

Quickstart

Zero to an enforced child-safety policy in under five minutes.

Authentication

Bearer keys, DID signatures, and when each applies.

API reference

Every endpoint, field, and error — with a live sandbox behind each one.