Postman & Insomnia collection
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
- 1Download both files
Grab the collection and the sandbox environment using the buttons above.
- 2Import them
In Postman, click Import (top-left) and drag both
.jsonfiles in — or paste the file URLs into the Import → Link box. Postman detects the OpenAPI-derived collection and the environment automatically. - 3Select the environment
In the environment dropdown (top-right), choose Phosra Sandbox.
baseUrlis already set to the live sandbox. - 4Add your key (optional for public reads)
Open the Phosra Sandbox environment, set
apiKeyto yourphosra_test_…key, and save. Get one from Create your account. Public endpoints — Platforms, Ratings, Standards — return200without a key. - 5Send a request
Open Platforms → List all platforms and press Send. You should get a
200with the seeded platform catalog. You are now talking to the live sandbox.
Import into Insomnia
Insomnia reads Postman v2.1 collections natively:
- 1Import 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. - 2Set the base environment
Open Manage Environments and add:
json{ "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 }}. - 3Send
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:
| Variable | Default | What it's for |
|---|---|---|
baseUrl | https://phosra-api-sandbox-production.up.railway.app/api/v1 | The synthetic hosted sandbox root. |
apiKey | phosra_test_REPLACE_ME | Your 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. |
There is no supported two-variable move to production. Production access requires a separately scoped design-partner pilot, provisioned credentials, and operational review.
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:
| Variable | Seeded with | How it gets a live value |
|---|---|---|
standardId | 33e8b8cf-… — the real Four Norms community standard | Works immediately: GET /standards and GET /standards/four-norms return it with no setup. |
familyId | the shared sandbox demo family | Overwritten the moment you run Setup → One-step onboarding or Create a family. |
childId | demo child Mia | Overwritten by One-step onboarding or Add child to family. |
policyId | Mia's demo policy | Overwritten by One-step onboarding or Create policy for child. |
ruleId, webhookId, sourceId, linkId, deviceId, jobId, memberId, feedbackId, ratingId | empty | Captured automatically by the matching Create request (see below). |
userId | empty | The 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:
| Request | Path binding | Resolves to |
|---|---|---|
| Platforms → Get platform details | platformID = apple | GET /platforms/apple → 200 |
| Platforms → Get OAuth authorization URL | platformID = microsoft | 200 — an OAuth-capable platform (device platforms like apple return 400 platform does not support OAuth) |
| Platforms → Handle OAuth callback | platformID = microsoft | 200 — but supply a real code from the authorize step; the seeded code is a labeled placeholder |
| Providers → Get provider connect config | did = did:ocss:loopline | GET /providers/did:ocss:loopline/connect → 200 |
| Standards → Get a community standard by slug | slug = four-norms | GET /standards/four-norms → 200 |
| Ratings → Get ratings for a specific rating system | systemID = esrb | GET /ratings/systems/esrb → 200 |
| Ratings → Get content descriptors for a rating system | systemID = esrb | 200 |
| Device Sync → Get platform-specific identifier mappings | platformID = apple | GET /platform-mappings/apple → 200 |
| Sources → Get guided steps | category = web_filtering | 200 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:
- 1Setup → One-step onboarding
POST /setup/quickreturns a family, child, policy, and starter rules in one call. Its test script setsfamilyId,childId,policyId, andruleIdfor you. - 2Anything 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/linkIdfor 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 sandbox setup → synthetic 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=TagsNext 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.