{"openapi":"3.1.0","info":{"title":"Prson human agents API","version":"2026-10-01","description":"Send verified people to do things in the physical world: put up posters, check a shelf, photograph a place, pick something up.\nPost a task with where, when, what proof you need and what you pay; Prson offers it to the closest suitable people,\nwho accept, do it and hand in proof captured with the Prson app (signed by the phone, located from its GPS track).\nYou approve or reject; approved work is paid from your prepaid balance.\nWork left without a decision for 7 days after it was handed in is approved automatically (the assignment.submitted webhook carries `auto_approve_at`).\nA reported stop stays yours to approve or reject even after its agent withdraws or the due date passes; one left undecided for 7 days after its report is approved automatically. A task with a reported stop waiting can't be cancelled (409 `stops_awaiting_review`): review it first.\n\nPay by country: set `pay_by_country` (your own amount per country) or `local_pay` (amounts scaled from a reference country by local price levels). Only people whose country is listed are offered the task, and each sees only their own country's amount (an estimate from where they work until they set up payouts; they're hired at their payout account's country rate). Posting reserves the highest amount; when someone is hired at a lower rate, the difference goes back to your balance at once, and the fee is charged on what they're actually paid.\nScreening: set `screening` to have people apply before they're hired, with a short video answering your prompt, or a voice interview (`kind: voice_interview`): you write the questions and a scoring guide, Prson asks them in the person's language and gives you a score, summary and transcript. Hire from GET /v1/tasks/{task_id}/applications.\nPay per result: set `pay_per_result` (e.g. per sale or sign-up, up to `max_results`). Each hired person gets a code (and a link when you give `landing_url`); report each result your system sees with POST /v1/tasks/{task_id}/results and the person is paid. People can also claim a result themselves; you approve or reject it, and one left undecided for 7 days is approved automatically.\n\nAuthenticate with your API key: `Authorization: Bearer prs_live_…`. Money is in minor units (cents).\nWebhooks tell you when things happen (see the Webhook schema). AI agents have an MCP server per product: Prson Verify (verifications) at /mcp/verify and Prson Human Agents (tasks) at /mcp/agents, with an API key or OAuth; /mcp serves both for clients connected before.\n\nVerifications: ask a person to prove something (a fact such as age ≥ 18, a verified name or nationality, a live selfie, an identity document) or to sign a PDF with their verified name (upload it with POST /v1/verifications/documents, then a document_signature requirement) with POST /v1/verifications (scope verifications:write).\nSend them the returned `share_url` yourself (Prson doesn't email or message them for you); they answer in the Prson app, choosing what to share. Poll GET /v1/verifications/{id} (verifications:read) or listen for verification.* webhooks.\nEach person appears only as a `respondent_id`: stable for your organisation, different for any other. GET /v1/verifications/requirements lists what can be asked for today.\nPricing, a flat price per source, not per requirement: creating a verification reserves the base (0.50: live photo, video, selfie, email); plus the person's ID chip once, 0.50 for any number of yes/no facts from their passport or ID card (age, nationality, document validity, issuing country, verification level, or a capture with require_document_verification or required_facts) or 1.00 if any requirement shares a value from it (a name, date of birth, nationality or document property with reveal_value true; facts included); plus 1.00 once for a PDF signature. In your balance's currency (EUR if you hold EUR, else your largest balance, or `currency`; the same number in each).\nPremium requirements (a phone, address or bank property or fact) add their premium each (GET /v1/verifications/requirements: `pricing.premium_cents`).\nDiscounts, off everything but premiums: 50% at launch, until 31 March 2027; by volume, 25% from your organisation's 1,001st production verification of a UTC month and 40% from the 10,001st (GET /v1/org/plan: `volume`). The larger one applies, never both, and a verification keeps the price it was created with (`charge.discount`). POST /v1/verifications/quote prices a body without creating anything.\nThe base is spent with the first verified answer, the ID chip with the first verified answer that used it, the signature with the signed PDF, and each premium with its requirement's first verified answer; the rest goes back when you cancel or it expires. Nobody answers: nothing is charged.\n\nApps and free plans: each API key belongs to an app of your organisation (keys without one, and OAuth-connected apps, to its default app). An app's plan decides its verification prices:\n`open_source` (1,000 a month free; approved automatically from GitHub: a public, non-fork repository with an OSI-approved licence, pushed within 6 months, holding a token file Prson issues, with one of the app's domains as its homepage, in its README or the owner's GitHub Pages; re-checked monthly) and\n`non_commercial` (100 a month free; reviewed by Prson). The allowance pays the base, ID chip and signature prices only; premiums are always charged. One verification takes one unit when created and gives it back if cancelled or expired with no verified answer; usage resets on the 1st (UTC).\nPast the allowance: 402 `allowance_exhausted`, or standard prices with `overage: \"charge\"` (PATCH /v1/org/plan). Apps in sandbox create free verifications marked `test: true` and can't email people. Human-agent tasks are never discounted.\nScopes: tasks:read and tasks:write (human-agent tasks), coverage:read (exact counts from /v1/coverage), verifications:read and verifications:write (verifications), and notify:write\n(POST /v1/notify: send a website notification to a person who opted in when signing in with Prson; API keys only, never by default, never through OAuth).\nToo many requests in a short time get 429 `too_many_requests` (and some routes have their own daily limits, named in the error): wait and retry.\nOrg-wide endpoints (balance, top-ups, ledger, webhooks, connected apps, apps and plans) accept either product's keys: tasks:read or verifications:read to read, tasks:write or verifications:write to change (changes need the org's API key, not an OAuth-connected app).\n\nChecking a verdict signature: each response carries `verdict_signature: { envelope, signature, kid }`. `signature` is RS256 (RSASSA-PKCS1-v1_5, SHA-256), base64, over the UTF-8 bytes of the canonical JSON of `envelope`\n(keys sorted at every level, no whitespace). Fetch Prson's keys from GET /v1/company/public-key (`verificationKeys[].publicKey`, PEM, by `kid`) and verify. The envelope names scope `prson-truth-verdict/2`, the proof, the verification\n(`challengeId` = the verification id), the requirement (`slotId`), the verdict `level` and `verifiedAt`; for your verifications `signerIdentityId` is the `respondent_id`.\nIt also commits to what was disclosed: `disclosures` holds one `{ kind, id, digest }` per value (kind `fact`, `property` or `document_field`; id the fact, the property type or the field name), and the response's\n`verdict_disclosures` holds the matching `[salt, kind, id, value]`. Each value is signed by Prson when base64url(SHA-256(canonical JSON of `[salt, kind, id, value]`)) equals the digest of the entry with that kind and id.\nKeep `verdict_disclosures` with the envelope and signature to prove later, offline, exactly what Prson vouched for; the envelope alone reveals no value. A property shared without its value has no entry."},"security":[{"apiKey":[]}],"paths":{"/v1/tasks":{"post":{"operationId":"createTask","summary":"Post a task","description":"Reserves the total (pay × slots + platform fee) from your balance and starts offering it. Send Idempotency-Key to make retries safe. Tasks are screened against the content policy: one that asks for illegal goods or services, sexual services, weapons, drugs, harassing or following a private person, fraud, or collecting other people's ID documents or credentials is refused (422 `task_not_allowed`, with a `reason`); a borderline one is created with `review_status: held` and offered to nobody until Prson reviews it.","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTask"}}}},"responses":{"200":{"description":"Replayed (same Idempotency-Key)","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"replayed":{"const":true}}}}}},"201":{"description":"Posted","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"offers_sent":{"type":"integer"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Not enough balance (error: insufficient_balance)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid, or refused by the content policy (error: task_not_allowed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"get":{"operationId":"listTasks","summary":"List your tasks, newest first","parameters":[{"name":"status","in":"query","schema":{"enum":["open","filled","completed","cancelled","expired"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"before","in":"query","schema":{"type":"integer"},"description":"created_at cursor (next_before from the last page)"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"next_before":{"type":["integer","null"]}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}":{"get":{"operationId":"getTask","summary":"A task with who took it and the proof they handed in","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"offers":{"type":"object","additionalProperties":{"type":"integer"},"description":"offer counts by status"},"assignments":{"type":"array","items":{"$ref":"#/components/schemas/Assignment"}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/cancel":{"post":{"operationId":"cancelTask","summary":"Cancel an open or filled task (the unused reserve returns to your balance)","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Not cancellable, or handed-in work awaits your decision (approved work stays paid; the unused rest of the reserve goes back)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/assignments/{assignment_id}/approve":{"post":{"operationId":"approveWork","summary":"Approve handed-in work (the person is paid)","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"assignment_id","in":"path","required":true,"schema":{"type":"string"},"description":"asg_…"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"assignment":{"type":"object"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Only submitted work","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/assignments/{assignment_id}/reject":{"post":{"operationId":"rejectWork","summary":"Reject handed-in work (the slot reopens)","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"assignment_id","in":"path","required":true,"schema":{"type":"string"},"description":"asg_…"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"assignment":{"type":"object"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Only submitted work","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/proofs/{proof_id}":{"get":{"operationId":"getProofFile","summary":"Download a proof photo or video","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"proof_id","in":"path","required":true,"schema":{"type":"string"},"description":"prf_…"}],"responses":{"200":{"description":"The file","content":{"image/*":{},"video/*":{}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/applications":{"get":{"operationId":"listApplications","summary":"People who applied to a screened task (video or voice interview)","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"sort","in":"query","schema":{"enum":["score"]},"description":"best interview score first (default: newest first)"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"screening":{"type":["object","null"],"description":"the task's screening, as posted"},"applications":{"type":"array","items":{"$ref":"#/components/schemas/Application"}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/applications/{application_id}/accept":{"post":{"operationId":"hireApplicant","summary":"Hire an applicant (they get an assignment at their country's rate)","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"application_id","in":"path","required":true,"schema":{"type":"string"},"description":"apl_…"}],"responses":{"201":{"description":"Hired","content":{"application/json":{"schema":{"type":"object","properties":{"application":{"type":"object"},"assignment":{"type":"object","properties":{"id":{"type":"string"},"status":{"const":"active"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"already_decided, no_free_slot, not_offered_in_your_country, payout_account_required (paying by country: the person must set up payouts first; their payout account sets their country), or not_funded (top up at least required_cents)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/applications/{application_id}/reject":{"post":{"operationId":"rejectApplicant","summary":"Turn an applicant down","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"application_id","in":"path","required":true,"schema":{"type":"string"},"description":"apl_…"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"application":{"type":"object"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"already_decided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/applications/{application_id}/video":{"get":{"operationId":"getApplicationVideo","summary":"Watch a video application","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"application_id","in":"path","required":true,"schema":{"type":"string"},"description":"apl_…"}],"responses":{"200":{"description":"The video","content":{"video/*":{}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/applications/{application_id}/answers/{index}/audio":{"get":{"operationId":"getInterviewAnswerAudio","summary":"Listen to one answer of a voice interview","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"application_id","in":"path","required":true,"schema":{"type":"string"},"description":"apl_…"},{"name":"index","in":"path","required":true,"schema":{"type":"integer"},"description":"transcript index"}],"responses":{"200":{"description":"The recording","content":{"audio/*":{}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/screening/suggest":{"post":{"operationId":"suggestScreening","summary":"Suggest voice interview questions and a scoring guide for a task","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","instructions"],"properties":{"title":{"type":"string"},"instructions":{"type":"string"},"language":{"type":"string","description":"ISO 639-1"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"questions":{"type":"array","items":{"type":"string"}},"rubric":{"type":"string"},"pass_score":{"type":"integer"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"},"503":{"description":"ai_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/tasks/{task_id}/results":{"get":{"operationId":"listResults","summary":"Results (sales, sign-ups) of a pay-per-result task, and each hired person's code","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"status","in":"query","schema":{"enum":["pending","approved","rejected"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"before","in":"query","schema":{"type":"integer"},"description":"created_at cursor (next_before from the last page)"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"pay_per_result":{"$ref":"#/components/schemas/Money"},"counts":{"type":"object","properties":{"pending":{"type":"integer"},"approved":{"type":"integer"},"rejected":{"type":"integer"}}},"results_left":{"type":"integer"},"spent":{"$ref":"#/components/schemas/Money"},"released_at":{"type":["integer","null"],"description":"when the unused results reserve went back to your balance"},"codes":{"type":"array","items":{"type":"object","properties":{"assignment_id":{"type":"string"},"agent":{"type":"object","properties":{"display_name":{"type":["string","null"]}}},"code":{"type":"string"},"link":{"type":["string","null"]},"pay_per_result":{"$ref":"#/components/schemas/Money"},"pay_country":{"type":["string","null"]},"window_ends_at":{"type":["integer","null"],"description":"results reported after this aren't accepted"}}}},"results":{"type":"array","items":{"$ref":"#/components/schemas/Result"}},"next_before":{"type":["integer","null"]}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"post":{"operationId":"reportResult","summary":"Report a result your system saw (approved and paid at once)","description":"Idempotent on external_ref: sending the same one again returns the first result (replayed: true). If the person already claimed that external_ref, this approves their claim.","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","external_ref"],"properties":{"code":{"type":"string","description":"the person's result code (case and dashes ignored)"},"external_ref":{"type":"string","maxLength":200,"description":"your order or sign-up id"},"value_cents":{"type":"integer","description":"what the sale was worth (for your records)"},"occurred_at":{"type":["integer","string"],"description":"epoch ms or ISO 8601"}}}}}},"responses":{"200":{"description":"Already recorded","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"$ref":"#/components/schemas/Result"},"replayed":{"const":true}}}}}},"201":{"description":"Recorded and paid","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"$ref":"#/components/schemas/Result"},"replayed":{"const":false}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"results_cap_reached, window_closed, external_ref_taken, result_rejected, not_funded or no_pay_per_result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/results/{result_id}/approve":{"post":{"operationId":"approveResult","summary":"Approve a result the person claimed (they're paid)","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"result_id","in":"path","required":true,"schema":{"type":"string"},"description":"res_…"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"$ref":"#/components/schemas/Result"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"not_pending, results_cap_reached, not_funded or window_closed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/tasks/{task_id}/results/{result_id}/reject":{"post":{"operationId":"rejectResult","summary":"Reject a result the person claimed","parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string"},"description":"tsk_…"},{"name":"result_id","in":"path","required":true,"schema":{"type":"string"},"description":"res_…"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"result":{"$ref":"#/components/schemas/Result"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"not_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/verifications":{"post":{"operationId":"createVerification","summary":"Ask a person to verify something","description":"Reserves the price from your balance (see the pricing rule above; 402 `insufficient_balance` with `required_cents` if it's short) and returns the verification with its `share_url`. Send the `share_url` to the person yourself (by email, chat or on your site): Prson doesn't contact them for you, and a body with `recipient_email` is refused (400 `email_not_supported`). Requirements Prson can't satisfy yet are refused (422 `requirement_not_available`), and so are a phone or postal-address property or fact where this environment can't verify them (422 `requirement_unavailable`: see `capabilities` in GET /v1/verifications/requirements). Send Idempotency-Key to make retries safe.","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVerification"},"example":{"title":"Confirm you're over 18 and show your ID to rent a car","requirements":[{"type":"fact","fact":"age_gte_18"},{"type":"property","property":"family_name"},{"type":"document","require_document_verification":true,"document_types":["passport","national_id"]},{"type":"selfie","optional":true}],"expires_in_hours":48,"external_ref":"booking-4821","metadata":{"branch":"Lisbon airport"}}}}},"responses":{"200":{"description":"Replayed (same Idempotency-Key)","content":{"application/json":{"schema":{"type":"object","properties":{"verification":{"$ref":"#/components/schemas/Verification"},"share_url":{"type":"string"},"replayed":{"const":true}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"verification":{"$ref":"#/components/schemas/Verification"},"share_url":{"type":"string"}}}}}},"400":{"description":"Invalid request (issues lists each problem), an invalid requirement (invalid_requirement), or recipient_email sent (email_not_supported: send share_url yourself)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Not enough balance (error: insufficient_balance), or the app's free plan allowance is used up for the month (error: allowance_exhausted, with allowance and resets_at)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A requirement can't be answered yet (requirement_not_available), phone or address verification isn't available here (requirement_unavailable), or the key's spend cap","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"get":{"operationId":"listVerifications","summary":"List your verifications, newest first (without responses)","parameters":[{"name":"status","in":"query","schema":{"enum":["open","partially_fulfilled","fulfilled","cancelled","expired"]}},{"name":"external_ref","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the last page"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"verifications":{"type":"array","items":{"$ref":"#/components/schemas/Verification"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/verifications/documents":{"post":{"operationId":"uploadVerificationDocument","summary":"Upload a PDF for a person to sign (a document_signature requirement)","description":"The body is the PDF (Content-Type application/pdf, file name in `?name=`), or JSON `{ content_base64, name }`. At most 12 MB, not encrypted. Returns its `id` (use it as `document_id`) and SHA-256. Kept a week for a verification to use, then as long as one does. The person signs it in the Prson app with a certificate naming them from their chip-read identity document: the signed PDF (PAdES B-T) is your file plus the signature, so its first `size` bytes hash to `sha256`. It is an advanced electronic signature under eIDAS, not a qualified one. Retention: the uploaded PDF is deleted a week after upload if no verification uses it, else once no verification refers to it; the signed PDF (with the answer) is deleted 30 days after the verification expires. Prson keeps no copy of a PDF a person signs for themselves, and no names: the signer's name is in the certificate inside the PDF and in the answer you receive.","parameters":[{"name":"name","in":"query","schema":{"type":"string","maxLength":120},"description":"the file name the person sees"}],"requestBody":{"required":true,"content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"object","required":["content_base64"],"properties":{"content_base64":{"type":"string"},"name":{"type":"string","maxLength":120}}}}}},"responses":{"201":{"description":"Stored","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"sha256":{"type":"string"},"size":{"type":"integer"},"pages":{"type":"integer"},"unused_expires_at":{"type":"integer"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Over 12 MB (document_too_large)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Not a PDF that can be signed: encrypted or unreadable (document_unsupported)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/verifications/requirements":{"get":{"operationId":"verificationRequirements","summary":"What a verification can ask for today: requirement types, fact ids and patterns, property types, document types, limits and prices","description":"`capabilities` says whether this environment can verify phone numbers (`phone_verification`: Firebase phone sign-in in the app) and postal addresses (`address_verification`: a code letter posted by Pingen). When one is false its property and facts (phone, phone_verified; address, address_*) are left out of `properties` and `facts` and listed under `not_available_yet`, and asking for them is refused with 422 `requirement_unavailable`.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"capabilities":{"type":"object","properties":{"phone_verification":{"type":"boolean"},"address_verification":{"type":"boolean"}},"required":["phone_verification","address_verification"]},"not_available_yet":{"type":"object","properties":{"properties":{"type":"array","items":{"type":"string"}},"facts_matching":{"type":"string","description":"a regular expression"}}}},"additionalProperties":true}}}}}}},"/v1/verifications/quote":{"post":{"operationId":"quoteVerification","summary":"What creating this verification would reserve now, without creating it","description":"Takes POST /v1/verifications's body (title optional) and prices it for your key's app: the regular price, the launch or volume discount, a free plan's allowance, and sandbox (free). Creates nothing, reserves nothing and takes no allowance unit.","x-scopes":["verifications:read"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVerification"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"quote":{"type":"object","properties":{"app_id":{"type":"string"},"test":{"type":"boolean","description":"a sandbox app: it would be free"},"currency":{"type":"string"},"regular_cents":{"type":"integer","description":"without any discount"},"discount":{"type":["object","null"],"properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"until":{"type":"string"},"ends_at":{"type":"integer"}}},"price_cents":{"type":"integer","description":"the standard price after the discount (before a free plan or sandbox)"},"premium_cents":{"type":"integer","description":"the part a free plan never covers"},"allowance":{"type":["object","null"],"properties":{"plan":{"type":"string"},"remaining":{"type":"integer"},"covers_cents":{"type":"integer"}}},"reserved_cents":{"type":["integer","null"],"description":"what creating it now would reserve; null when the allowance is used up and overage is refuse (402)"},"sources":{"type":"object","description":"what this verification pays for once each: the ID chip (yes/no facts only, or details, which include the facts) and a PDF signature","properties":{"document":{"enum":["facts","details"]},"signature":{"const":true}}},"source_cents":{"type":"object","description":"each source's price after the discount","properties":{"base":{"type":"integer"},"document":{"type":"integer"},"signature":{"type":"integer"}}},"requirements":{"type":"array","items":{"type":"object","properties":{"requirement":{"type":"integer"},"source":{"enum":["document_facts","document_details","signature",null],"description":"the source it uses; null: the base covers it"},"premium_cents":{"type":"integer"}}}}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/verifications/{verification_id}":{"get":{"operationId":"getVerification","summary":"A verification with every answer so far","parameters":[{"name":"verification_id","in":"path","required":true,"schema":{"type":"string"},"description":"the verification id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"verification":{"$ref":"#/components/schemas/Verification"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/verifications/{verification_id}/proofs/{proof_id}/{file}":{"get":{"operationId":"getVerificationFile","summary":"An answer's file: photo (JPEG), video (MP4), sensors (JSON) or signed_pdf (a document signature's signed PDF); the names in the response's `files`","parameters":[{"name":"verification_id","in":"path","required":true,"schema":{"type":"string"},"description":"the verification id"},{"name":"proof_id","in":"path","required":true,"schema":{"type":"string"},"description":"the response's proof_id"},{"name":"file","in":"path","required":true,"schema":{"enum":["photo","video","sensors","signed_pdf"]}}],"responses":{"200":{"description":"The bytes (Range requests supported)"},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/verifications/{verification_id}/cancel":{"post":{"operationId":"cancelVerification","summary":"Stop accepting answers; what the reserve still holds goes back to your balance","parameters":[{"name":"verification_id","in":"path","required":true,"schema":{"type":"string"},"description":"the verification id"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"verification":{"$ref":"#/components/schemas/Verification"},"released_cents":{"type":"integer"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Already cancelled or expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/coverage":{"get":{"operationId":"coverageAt","summary":"How many people would travel to a point","parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number"}},{"name":"lng","in":"query","required":true,"schema":{"type":"number"}},{"name":"skill","in":"query","schema":{"type":"string"}},{"name":"min_level","in":"query","schema":{"type":"integer","minimum":0,"maximum":6}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"cell":{"type":"string"},"available":{"type":"object","properties":{"count":{"type":["integer","null"]},"label":{"type":"string","example":"20+"}}},"skills":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"}}}}}}}}}}}},"/v1/org":{"get":{"operationId":"getOrg","summary":"Your organisation, this key, task counts and prepaid balances","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"org":{"type":"object"},"api_key":{"type":"object","description":"this key: prefix, scopes, spend_cap_cents, committed_cents"},"tasks":{"type":"object","additionalProperties":{"type":"integer"},"description":"task counts by status"},"balances":{"type":"array","items":{"$ref":"#/components/schemas/Balance"}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/apps":{"get":{"operationId":"listApps","summary":"Your organisation's apps","x-scopes":["tasks:read","verifications:read"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"apps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"environment":{"enum":["sandbox","production"]},"plan":{"type":"string"},"plan_status":{"type":"string"},"allowance":{"type":"integer"},"overage":{"type":"string"},"is_default":{"type":"boolean"}}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"post":{"operationId":"createApp","summary":"A new app (sandbox until it qualifies for production)","x-scopes":["tasks:write","verifications:write"],"x-api-key-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"environment":{"enum":["sandbox","production"]},"plan":{"type":"string"},"plan_status":{"type":"string"},"allowance":{"type":"integer"},"overage":{"type":"string"},"is_default":{"type":"boolean"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/apps/{app_id}":{"get":{"operationId":"getApp","summary":"One app","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"x-scopes":["tasks:read","verifications:read"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"environment":{"enum":["sandbox","production"]},"plan":{"type":"string"},"plan_status":{"type":"string"},"allowance":{"type":"integer"},"overage":{"type":"string"},"is_default":{"type":"boolean"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"patch":{"operationId":"updateApp","summary":"Rename an app or set its domains","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"x-scopes":["tasks:write","verifications:write"],"x-api-key-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"environment":{"enum":["sandbox","production"]},"plan":{"type":"string"},"plan_status":{"type":"string"},"allowance":{"type":"integer"},"overage":{"type":"string"},"is_default":{"type":"boolean"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/apps/{app_id}/plan":{"get":{"operationId":"getAppPlan","summary":"The app's plan, this month's usage and its applications","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"x-scopes":["tasks:read","verifications:read"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"environment":{"enum":["sandbox","production"]},"is_default":{"type":"boolean"},"domains":{"type":"array","items":{"type":"string"}}}},"plan":{"enum":["standard","open_source","non_commercial"]},"status":{"enum":["active","awaiting_proof","pending"],"description":"active, or where an application for `plan` stands"},"allowance":{"type":"integer","description":"free verifications this month (0 unless the plan is active)"},"used":{"type":"integer"},"remaining":{"type":"integer"},"period":{"type":"string","example":"2026-11"},"resets_at":{"type":"integer","description":"Unix ms, the 1st of next month (UTC)"},"overage":{"enum":["refuse","charge"]},"since":{"type":["integer","null"]},"volume":{"type":"object","description":"the volume discount, counted per organisation over its production verifications this UTC month (not cancelled; sandbox doesn't count)","properties":{"scope":{"const":"organisation"},"period":{"type":"string","example":"2026-11"},"verifications_this_month":{"type":"integer"},"volume_discount_percent":{"type":"integer","description":"what the next verification gets by volume: 0, 25 (from the 1,001st) or 40 (from the 10,001st)"},"next_tier":{"type":["object","null"],"properties":{"from_verification":{"type":"integer"},"percent":{"type":"integer"},"verifications_to_go":{"type":"integer"}}},"current_discount":{"type":["object","null"],"description":"what the next production verification gets: the launch or the volume discount, whichever is larger","properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"until":{"type":"string"},"ends_at":{"type":"integer"}}},"resets_at":{"type":"integer"}}},"applications":{"type":"array","items":{"type":"object"},"description":"the latest applications, newest first"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"patch":{"operationId":"setAppOverage","summary":"What happens past the allowance: refuse (402 allowance_exhausted, the default) or charge standard prices","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"x-scopes":["tasks:write","verifications:write"],"x-api-key-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["overage"],"properties":{"overage":{"enum":["refuse","charge"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"environment":{"enum":["sandbox","production"]},"is_default":{"type":"boolean"},"domains":{"type":"array","items":{"type":"string"}}}},"plan":{"enum":["standard","open_source","non_commercial"]},"status":{"enum":["active","awaiting_proof","pending"],"description":"active, or where an application for `plan` stands"},"allowance":{"type":"integer","description":"free verifications this month (0 unless the plan is active)"},"used":{"type":"integer"},"remaining":{"type":"integer"},"period":{"type":"string","example":"2026-11"},"resets_at":{"type":"integer","description":"Unix ms, the 1st of next month (UTC)"},"overage":{"enum":["refuse","charge"]},"since":{"type":["integer","null"]},"volume":{"type":"object","description":"the volume discount, counted per organisation over its production verifications this UTC month (not cancelled; sandbox doesn't count)","properties":{"scope":{"const":"organisation"},"period":{"type":"string","example":"2026-11"},"verifications_this_month":{"type":"integer"},"volume_discount_percent":{"type":"integer","description":"what the next verification gets by volume: 0, 25 (from the 1,001st) or 40 (from the 10,001st)"},"next_tier":{"type":["object","null"],"properties":{"from_verification":{"type":"integer"},"percent":{"type":"integer"},"verifications_to_go":{"type":"integer"}}},"current_discount":{"type":["object","null"],"description":"what the next production verification gets: the launch or the volume discount, whichever is larger","properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"until":{"type":"string"},"ends_at":{"type":"integer"}}},"resets_at":{"type":"integer"}}},"applications":{"type":"array","items":{"type":"object"},"description":"the latest applications, newest first"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/apps/{app_id}/plan/open-source/apply":{"post":{"operationId":"applyAppOpenSource","summary":"Apply for the free open source plan: returns the token file to commit","description":"The repository must already qualify (public, not a fork, OSI-approved licence, pushed within 6 months): else 422 `not_eligible` with `checks`. 503 `github_unavailable` when GitHub can't answer.","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"x-scopes":["tasks:write","verifications:write"],"x-api-key-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["repo_url"],"properties":{"repo_url":{"type":"string","example":"https://github.com/acme/widget"},"domains":{"type":"array","items":{"type":"string"},"maxItems":20,"description":"the app's domains or OAuth redirect hosts (added to the app's)"},"contact_email":{"type":"string","description":"where plan emails go (default: your access request's email)"}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"application":{"type":"object"},"token_file":{"type":"object","properties":{"paths":{"type":"array","items":{"type":"string"}},"content":{"type":"string"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"not_eligible (with checks)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/apps/{app_id}/plan/open-source/verify":{"post":{"operationId":"verifyAppOpenSource","summary":"Check the repository now (token file, domain and the rest); the plan starts at once when every check passes","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"x-scopes":["tasks:write","verifications:write"],"x-api-key-only":true,"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"verified":{"type":"boolean"},"reasons":{"type":"array","items":{"type":"string"}},"checks":{"type":"object"},"application":{"type":"object"},"plan":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"environment":{"enum":["sandbox","production"]},"is_default":{"type":"boolean"},"domains":{"type":"array","items":{"type":"string"}}}},"plan":{"enum":["standard","open_source","non_commercial"]},"status":{"enum":["active","awaiting_proof","pending"],"description":"active, or where an application for `plan` stands"},"allowance":{"type":"integer","description":"free verifications this month (0 unless the plan is active)"},"used":{"type":"integer"},"remaining":{"type":"integer"},"period":{"type":"string","example":"2026-11"},"resets_at":{"type":"integer","description":"Unix ms, the 1st of next month (UTC)"},"overage":{"enum":["refuse","charge"]},"since":{"type":["integer","null"]},"volume":{"type":"object","description":"the volume discount, counted per organisation over its production verifications this UTC month (not cancelled; sandbox doesn't count)","properties":{"scope":{"const":"organisation"},"period":{"type":"string","example":"2026-11"},"verifications_this_month":{"type":"integer"},"volume_discount_percent":{"type":"integer","description":"what the next verification gets by volume: 0, 25 (from the 1,001st) or 40 (from the 10,001st)"},"next_tier":{"type":["object","null"],"properties":{"from_verification":{"type":"integer"},"percent":{"type":"integer"},"verifications_to_go":{"type":"integer"}}},"current_discount":{"type":["object","null"],"description":"what the next production verification gets: the launch or the volume discount, whichever is larger","properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"until":{"type":"string"},"ends_at":{"type":"integer"}}},"resets_at":{"type":"integer"}}},"applications":{"type":"array","items":{"type":"object"},"description":"the latest applications, newest first"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/apps/{app_id}/plan/non-commercial/apply":{"post":{"operationId":"applyAppNonCommercial","summary":"Apply for the free non-commercial plan (pending until Prson approves it)","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"x-scopes":["tasks:write","verifications:write"],"x-api-key-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["project_name","purpose","website","accept_terms","terms_version"],"properties":{"project_name":{"type":"string","maxLength":120},"purpose":{"type":"string","minLength":20,"maxLength":2000},"website":{"type":"string","format":"uri"},"accept_terms":{"const":true},"terms_version":{"type":"string","description":"the non-commercial terms version (GET /v1/verifications/requirements: plans.non_commercial.terms_version)"},"contact_email":{"type":"string"}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"application":{"type":"object"},"terms_version":{"type":"string"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"terms_outdated or already_on_plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/plan":{"get":{"operationId":"getOwnPlan","summary":"The app's plan, this month's usage and its applications","parameters":[],"x-scopes":["tasks:read","verifications:read"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"environment":{"enum":["sandbox","production"]},"is_default":{"type":"boolean"},"domains":{"type":"array","items":{"type":"string"}}}},"plan":{"enum":["standard","open_source","non_commercial"]},"status":{"enum":["active","awaiting_proof","pending"],"description":"active, or where an application for `plan` stands"},"allowance":{"type":"integer","description":"free verifications this month (0 unless the plan is active)"},"used":{"type":"integer"},"remaining":{"type":"integer"},"period":{"type":"string","example":"2026-11"},"resets_at":{"type":"integer","description":"Unix ms, the 1st of next month (UTC)"},"overage":{"enum":["refuse","charge"]},"since":{"type":["integer","null"]},"volume":{"type":"object","description":"the volume discount, counted per organisation over its production verifications this UTC month (not cancelled; sandbox doesn't count)","properties":{"scope":{"const":"organisation"},"period":{"type":"string","example":"2026-11"},"verifications_this_month":{"type":"integer"},"volume_discount_percent":{"type":"integer","description":"what the next verification gets by volume: 0, 25 (from the 1,001st) or 40 (from the 10,001st)"},"next_tier":{"type":["object","null"],"properties":{"from_verification":{"type":"integer"},"percent":{"type":"integer"},"verifications_to_go":{"type":"integer"}}},"current_discount":{"type":["object","null"],"description":"what the next production verification gets: the launch or the volume discount, whichever is larger","properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"until":{"type":"string"},"ends_at":{"type":"integer"}}},"resets_at":{"type":"integer"}}},"applications":{"type":"array","items":{"type":"object"},"description":"the latest applications, newest first"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"patch":{"operationId":"setOwnOverage","summary":"What happens past the allowance: refuse (402 allowance_exhausted, the default) or charge standard prices","parameters":[],"x-scopes":["tasks:write","verifications:write"],"x-api-key-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["overage"],"properties":{"overage":{"enum":["refuse","charge"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"environment":{"enum":["sandbox","production"]},"is_default":{"type":"boolean"},"domains":{"type":"array","items":{"type":"string"}}}},"plan":{"enum":["standard","open_source","non_commercial"]},"status":{"enum":["active","awaiting_proof","pending"],"description":"active, or where an application for `plan` stands"},"allowance":{"type":"integer","description":"free verifications this month (0 unless the plan is active)"},"used":{"type":"integer"},"remaining":{"type":"integer"},"period":{"type":"string","example":"2026-11"},"resets_at":{"type":"integer","description":"Unix ms, the 1st of next month (UTC)"},"overage":{"enum":["refuse","charge"]},"since":{"type":["integer","null"]},"volume":{"type":"object","description":"the volume discount, counted per organisation over its production verifications this UTC month (not cancelled; sandbox doesn't count)","properties":{"scope":{"const":"organisation"},"period":{"type":"string","example":"2026-11"},"verifications_this_month":{"type":"integer"},"volume_discount_percent":{"type":"integer","description":"what the next verification gets by volume: 0, 25 (from the 1,001st) or 40 (from the 10,001st)"},"next_tier":{"type":["object","null"],"properties":{"from_verification":{"type":"integer"},"percent":{"type":"integer"},"verifications_to_go":{"type":"integer"}}},"current_discount":{"type":["object","null"],"description":"what the next production verification gets: the launch or the volume discount, whichever is larger","properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"until":{"type":"string"},"ends_at":{"type":"integer"}}},"resets_at":{"type":"integer"}}},"applications":{"type":"array","items":{"type":"object"},"description":"the latest applications, newest first"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/plan/open-source/apply":{"post":{"operationId":"applyOwnOpenSource","summary":"Apply for the free open source plan: returns the token file to commit","description":"The repository must already qualify (public, not a fork, OSI-approved licence, pushed within 6 months): else 422 `not_eligible` with `checks`. 503 `github_unavailable` when GitHub can't answer.","parameters":[],"x-scopes":["tasks:write","verifications:write"],"x-api-key-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["repo_url"],"properties":{"repo_url":{"type":"string","example":"https://github.com/acme/widget"},"domains":{"type":"array","items":{"type":"string"},"maxItems":20,"description":"the app's domains or OAuth redirect hosts (added to the app's)"},"contact_email":{"type":"string","description":"where plan emails go (default: your access request's email)"}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"application":{"type":"object"},"token_file":{"type":"object","properties":{"paths":{"type":"array","items":{"type":"string"}},"content":{"type":"string"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"not_eligible (with checks)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/plan/open-source/verify":{"post":{"operationId":"verifyOwnOpenSource","summary":"Check the repository now (token file, domain and the rest); the plan starts at once when every check passes","parameters":[],"x-scopes":["tasks:write","verifications:write"],"x-api-key-only":true,"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"verified":{"type":"boolean"},"reasons":{"type":"array","items":{"type":"string"}},"checks":{"type":"object"},"application":{"type":"object"},"plan":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"environment":{"enum":["sandbox","production"]},"is_default":{"type":"boolean"},"domains":{"type":"array","items":{"type":"string"}}}},"plan":{"enum":["standard","open_source","non_commercial"]},"status":{"enum":["active","awaiting_proof","pending"],"description":"active, or where an application for `plan` stands"},"allowance":{"type":"integer","description":"free verifications this month (0 unless the plan is active)"},"used":{"type":"integer"},"remaining":{"type":"integer"},"period":{"type":"string","example":"2026-11"},"resets_at":{"type":"integer","description":"Unix ms, the 1st of next month (UTC)"},"overage":{"enum":["refuse","charge"]},"since":{"type":["integer","null"]},"volume":{"type":"object","description":"the volume discount, counted per organisation over its production verifications this UTC month (not cancelled; sandbox doesn't count)","properties":{"scope":{"const":"organisation"},"period":{"type":"string","example":"2026-11"},"verifications_this_month":{"type":"integer"},"volume_discount_percent":{"type":"integer","description":"what the next verification gets by volume: 0, 25 (from the 1,001st) or 40 (from the 10,001st)"},"next_tier":{"type":["object","null"],"properties":{"from_verification":{"type":"integer"},"percent":{"type":"integer"},"verifications_to_go":{"type":"integer"}}},"current_discount":{"type":["object","null"],"description":"what the next production verification gets: the launch or the volume discount, whichever is larger","properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"until":{"type":"string"},"ends_at":{"type":"integer"}}},"resets_at":{"type":"integer"}}},"applications":{"type":"array","items":{"type":"object"},"description":"the latest applications, newest first"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/plan/non-commercial/apply":{"post":{"operationId":"applyOwnNonCommercial","summary":"Apply for the free non-commercial plan (pending until Prson approves it)","parameters":[],"x-scopes":["tasks:write","verifications:write"],"x-api-key-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["project_name","purpose","website","accept_terms","terms_version"],"properties":{"project_name":{"type":"string","maxLength":120},"purpose":{"type":"string","minLength":20,"maxLength":2000},"website":{"type":"string","format":"uri"},"accept_terms":{"const":true},"terms_version":{"type":"string","description":"the non-commercial terms version (GET /v1/verifications/requirements: plans.non_commercial.terms_version)"},"contact_email":{"type":"string"}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"application":{"type":"object"},"terms_version":{"type":"string"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"terms_outdated or already_on_plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/dev/apps/{app_id}/plan":{"get":{"operationId":"getDevAppPlan","summary":"The app's plan, this month's usage and its applications","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"environment":{"enum":["sandbox","production"]},"is_default":{"type":"boolean"},"domains":{"type":"array","items":{"type":"string"}}}},"plan":{"enum":["standard","open_source","non_commercial"]},"status":{"enum":["active","awaiting_proof","pending"],"description":"active, or where an application for `plan` stands"},"allowance":{"type":"integer","description":"free verifications this month (0 unless the plan is active)"},"used":{"type":"integer"},"remaining":{"type":"integer"},"period":{"type":"string","example":"2026-11"},"resets_at":{"type":"integer","description":"Unix ms, the 1st of next month (UTC)"},"overage":{"enum":["refuse","charge"]},"since":{"type":["integer","null"]},"volume":{"type":"object","description":"the volume discount, counted per organisation over its production verifications this UTC month (not cancelled; sandbox doesn't count)","properties":{"scope":{"const":"organisation"},"period":{"type":"string","example":"2026-11"},"verifications_this_month":{"type":"integer"},"volume_discount_percent":{"type":"integer","description":"what the next verification gets by volume: 0, 25 (from the 1,001st) or 40 (from the 10,001st)"},"next_tier":{"type":["object","null"],"properties":{"from_verification":{"type":"integer"},"percent":{"type":"integer"},"verifications_to_go":{"type":"integer"}}},"current_discount":{"type":["object","null"],"description":"what the next production verification gets: the launch or the volume discount, whichever is larger","properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"until":{"type":"string"},"ends_at":{"type":"integer"}}},"resets_at":{"type":"integer"}}},"applications":{"type":"array","items":{"type":"object"},"description":"the latest applications, newest first"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}},"security":[{"developerSession":[]}],"tags":["Developer console"]},"patch":{"operationId":"setDevAppOverage","summary":"What happens past the allowance: refuse (402 allowance_exhausted, the default) or charge standard prices","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["overage"],"properties":{"overage":{"enum":["refuse","charge"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"environment":{"enum":["sandbox","production"]},"is_default":{"type":"boolean"},"domains":{"type":"array","items":{"type":"string"}}}},"plan":{"enum":["standard","open_source","non_commercial"]},"status":{"enum":["active","awaiting_proof","pending"],"description":"active, or where an application for `plan` stands"},"allowance":{"type":"integer","description":"free verifications this month (0 unless the plan is active)"},"used":{"type":"integer"},"remaining":{"type":"integer"},"period":{"type":"string","example":"2026-11"},"resets_at":{"type":"integer","description":"Unix ms, the 1st of next month (UTC)"},"overage":{"enum":["refuse","charge"]},"since":{"type":["integer","null"]},"volume":{"type":"object","description":"the volume discount, counted per organisation over its production verifications this UTC month (not cancelled; sandbox doesn't count)","properties":{"scope":{"const":"organisation"},"period":{"type":"string","example":"2026-11"},"verifications_this_month":{"type":"integer"},"volume_discount_percent":{"type":"integer","description":"what the next verification gets by volume: 0, 25 (from the 1,001st) or 40 (from the 10,001st)"},"next_tier":{"type":["object","null"],"properties":{"from_verification":{"type":"integer"},"percent":{"type":"integer"},"verifications_to_go":{"type":"integer"}}},"current_discount":{"type":["object","null"],"description":"what the next production verification gets: the launch or the volume discount, whichever is larger","properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"until":{"type":"string"},"ends_at":{"type":"integer"}}},"resets_at":{"type":"integer"}}},"applications":{"type":"array","items":{"type":"object"},"description":"the latest applications, newest first"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}},"security":[{"developerSession":[]}],"tags":["Developer console"]}},"/v1/dev/apps/{app_id}/plan/open-source/apply":{"post":{"operationId":"applyDevAppOpenSource","summary":"Apply for the free open source plan: returns the token file to commit","description":"The repository must already qualify (public, not a fork, OSI-approved licence, pushed within 6 months): else 422 `not_eligible` with `checks`. 503 `github_unavailable` when GitHub can't answer.","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["repo_url"],"properties":{"repo_url":{"type":"string","example":"https://github.com/acme/widget"},"domains":{"type":"array","items":{"type":"string"},"maxItems":20,"description":"the app's domains or OAuth redirect hosts (added to the app's)"},"contact_email":{"type":"string","description":"where plan emails go (default: your access request's email)"}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"application":{"type":"object"},"token_file":{"type":"object","properties":{"paths":{"type":"array","items":{"type":"string"}},"content":{"type":"string"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"not_eligible (with checks)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}},"security":[{"developerSession":[]}],"tags":["Developer console"]}},"/v1/dev/apps/{app_id}/plan/open-source/verify":{"post":{"operationId":"verifyDevAppOpenSource","summary":"Check the repository now (token file, domain and the rest); the plan starts at once when every check passes","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"verified":{"type":"boolean"},"reasons":{"type":"array","items":{"type":"string"}},"checks":{"type":"object"},"application":{"type":"object"},"plan":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"environment":{"enum":["sandbox","production"]},"is_default":{"type":"boolean"},"domains":{"type":"array","items":{"type":"string"}}}},"plan":{"enum":["standard","open_source","non_commercial"]},"status":{"enum":["active","awaiting_proof","pending"],"description":"active, or where an application for `plan` stands"},"allowance":{"type":"integer","description":"free verifications this month (0 unless the plan is active)"},"used":{"type":"integer"},"remaining":{"type":"integer"},"period":{"type":"string","example":"2026-11"},"resets_at":{"type":"integer","description":"Unix ms, the 1st of next month (UTC)"},"overage":{"enum":["refuse","charge"]},"since":{"type":["integer","null"]},"volume":{"type":"object","description":"the volume discount, counted per organisation over its production verifications this UTC month (not cancelled; sandbox doesn't count)","properties":{"scope":{"const":"organisation"},"period":{"type":"string","example":"2026-11"},"verifications_this_month":{"type":"integer"},"volume_discount_percent":{"type":"integer","description":"what the next verification gets by volume: 0, 25 (from the 1,001st) or 40 (from the 10,001st)"},"next_tier":{"type":["object","null"],"properties":{"from_verification":{"type":"integer"},"percent":{"type":"integer"},"verifications_to_go":{"type":"integer"}}},"current_discount":{"type":["object","null"],"description":"what the next production verification gets: the launch or the volume discount, whichever is larger","properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"until":{"type":"string"},"ends_at":{"type":"integer"}}},"resets_at":{"type":"integer"}}},"applications":{"type":"array","items":{"type":"object"},"description":"the latest applications, newest first"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}},"security":[{"developerSession":[]}],"tags":["Developer console"]}},"/v1/dev/apps/{app_id}/plan/non-commercial/apply":{"post":{"operationId":"applyDevAppNonCommercial","summary":"Apply for the free non-commercial plan (pending until Prson approves it)","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["project_name","purpose","website","accept_terms","terms_version"],"properties":{"project_name":{"type":"string","maxLength":120},"purpose":{"type":"string","minLength":20,"maxLength":2000},"website":{"type":"string","format":"uri"},"accept_terms":{"const":true},"terms_version":{"type":"string","description":"the non-commercial terms version (GET /v1/verifications/requirements: plans.non_commercial.terms_version)"},"contact_email":{"type":"string"}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"application":{"type":"object"},"terms_version":{"type":"string"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"terms_outdated or already_on_plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}},"security":[{"developerSession":[]}],"tags":["Developer console"]}},"/v1/dev/sign-in/nonce":{"post":{"operationId":"devSignInNonce","summary":"A single-use nonce for Sign in with Prson (valid 5 minutes)","description":"Pass it to the login SDK: signIn({ nonce, required: { uniqueHumanId: true } }) on your console page. `audiences` lists the KB-JWT audiences this API accepts (https://prson.net in production).","security":[],"tags":["Developer console"],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"nonce":{"type":"string"},"expires_at":{"type":"integer"},"audiences":{"type":"array","items":{"type":"string"}}}}}}}}}},"/v1/dev/sign-in":{"post":{"operationId":"devSignIn","summary":"Sign in with a Prson presentation: returns a developer session token","description":"Checked here: Prson's signature on the credential (its own keys, never a revoked one), its status list entry, and the KB-JWT, signed by the credential's holder key, with `aud` https://prson.net, `nonce` from /v1/dev/sign-in/nonce (taken once, whatever the outcome) and `iat` within 2 minutes. `unique_human_id` (the SDK result's uniqueHumanId): Prson-signed, audience prson.net, chip-verified (`trustTier: nfc`), and carrying this nonce or signed in the last 5 minutes. Its `uniqueIdHash` becomes the developer's owner_human_id: one app per person goes to production automatically. Without it the developer builds in sandbox only. The first sign-in makes an organisation with one sandbox app; later ones (the same wallet key, or the same unique-human id from another phone) find it. `claim`: the one-time code from an approved access request's email, making that organisation yours. 401 `invalid_nonce`, `presentation_rejected` (with `reason`: aud_mismatch, nonce_mismatch, kb_iat_stale, issuer_sig_invalid, vc_revoked…) or `unique_human_id_rejected`; 410 `claim_invalid`; 409 `account_has_org` or `different_person`.","security":[],"tags":["Developer console"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["presentation","nonce"],"properties":{"presentation":{"type":"string","description":"The SD-JWT-VC presentation with its KB-JWT (the SDK result's sdJwtVc)"},"nonce":{"type":"string"},"unique_human_id":{"type":["object","null"],"properties":{"envelope":{"type":"object"},"signature":{"type":"string"},"kid":{"type":"string"}}},"claim":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","description":"prs_ds_…"},"token_type":{"const":"Bearer"},"expires_at":{"type":"integer"},"expires_in":{"type":"integer"},"account":{"type":"object","properties":{"id":{"type":"string"},"verified_human":{"type":"boolean"},"verification_level":{"type":["integer","null"]}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/dev/sign-out":{"post":{"operationId":"devSignOut","summary":"End this developer session","security":[{"developerSession":[]}],"tags":["Developer console"],"responses":{"204":{"description":"Signed out"},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/dev/me":{"get":{"operationId":"devMe","summary":"The developer, their organisation, balances, the key scopes they may grant and what production needs","security":[{"developerSession":[]}],"tags":["Developer console"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/dev/org":{"patch":{"operationId":"devRenameOrg","summary":"Rename the organisation","security":[{"developerSession":[]}],"tags":["Developer console"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/dev/apps":{"get":{"operationId":"devListApps","summary":"The organisation's apps","security":[{"developerSession":[]}],"tags":["Developer console"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"apps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"environment":{"enum":["sandbox","production"]},"production_via":{"type":["string","null"]},"plan":{"type":"string"},"is_default":{"type":"boolean"}}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"post":{"operationId":"devCreateApp","summary":"A new app (sandbox until the production rule or Prson moves it)","security":[{"developerSession":[]}],"tags":["Developer console"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}}},"required":["name"]}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"environment":{"enum":["sandbox","production"]},"production_via":{"type":["string","null"]},"plan":{"type":"string"},"is_default":{"type":"boolean"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/dev/apps/{app_id}":{"get":{"operationId":"devGetApp","summary":"One app, this month's usage and any pending production request","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"security":[{"developerSession":[]}],"tags":["Developer console"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"environment":{"enum":["sandbox","production"]},"production_via":{"type":["string","null"]},"plan":{"type":"string"},"is_default":{"type":"boolean"}}},"usage":{"type":"object"},"production_request":{"type":["object","null"]}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"patch":{"operationId":"devUpdateApp","summary":"Rename it or set its domains and OAuth redirect hosts","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"security":[{"developerSession":[]}],"tags":["Developer console"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"app":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"domains":{"type":"array","items":{"type":"string"}},"environment":{"enum":["sandbox","production"]},"production_via":{"type":["string","null"]},"plan":{"type":"string"},"is_default":{"type":"boolean"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/dev/apps/{app_id}/keys":{"get":{"operationId":"devListKeys","summary":"The app's keys (never the secret)","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"security":[{"developerSession":[]}],"tags":["Developer console"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"prefix":{"type":"string","description":"The key's first characters, for recognising it"},"label":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"spend_cap_cents":{"type":["integer","null"]},"created_at":{"type":"integer"},"last_used_at":{"type":["integer","null"]},"expires_at":{"type":["integer","null"],"description":"Set on a rotated key: it stops at this time"},"revoked_at":{"type":["integer","null"]},"replaced_by":{"type":["string","null"]},"status":{"enum":["active","expiring","revoked"]}}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"post":{"operationId":"devCreateKey","summary":"A new key, shown once","description":"Scopes default to verifications:read and verifications:write; task scopes only where Prson approved them for the organisation (else 403 `scope_not_allowed`). A sandbox app's keys start with prs_sandbox_.","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"security":[{"developerSession":[]}],"tags":["Developer console"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"spend_cap_cents":{"type":["integer","null"]}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"allOf":[{"type":"object","properties":{"id":{"type":"string"},"prefix":{"type":"string","description":"The key's first characters, for recognising it"},"label":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"spend_cap_cents":{"type":["integer","null"]},"created_at":{"type":"integer"},"last_used_at":{"type":["integer","null"]},"expires_at":{"type":["integer","null"],"description":"Set on a rotated key: it stops at this time"},"revoked_at":{"type":["integer","null"]},"replaced_by":{"type":["string","null"]},"status":{"enum":["active","expiring","revoked"]}}},{"type":"object","properties":{"key":{"type":"string","description":"The raw key: in this response only. Prson keeps its SHA-256."}}}]},"environment":{"enum":["sandbox","production"]}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/dev/apps/{app_id}/keys/{key_id}/rotate":{"post":{"operationId":"devRotateKey","summary":"A new key with the same label, scopes and cap; the old one keeps working for 24 hours","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"},{"name":"key_id","in":"path","required":true,"schema":{"type":"string"},"description":"key_…"}],"security":[{"developerSession":[]}],"tags":["Developer console"],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"api_key":{"allOf":[{"type":"object","properties":{"id":{"type":"string"},"prefix":{"type":"string","description":"The key's first characters, for recognising it"},"label":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"spend_cap_cents":{"type":["integer","null"]},"created_at":{"type":"integer"},"last_used_at":{"type":["integer","null"]},"expires_at":{"type":["integer","null"],"description":"Set on a rotated key: it stops at this time"},"revoked_at":{"type":["integer","null"]},"replaced_by":{"type":["string","null"]},"status":{"enum":["active","expiring","revoked"]}}},{"type":"object","properties":{"key":{"type":"string","description":"The raw key: in this response only. Prson keeps its SHA-256."}}}]},"previous":{"type":"object","properties":{"id":{"type":"string"},"prefix":{"type":"string","description":"The key's first characters, for recognising it"},"label":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"spend_cap_cents":{"type":["integer","null"]},"created_at":{"type":"integer"},"last_used_at":{"type":["integer","null"]},"expires_at":{"type":["integer","null"],"description":"Set on a rotated key: it stops at this time"},"revoked_at":{"type":["integer","null"]},"replaced_by":{"type":["string","null"]},"status":{"enum":["active","expiring","revoked"]}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"key_not_active","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/dev/apps/{app_id}/keys/{key_id}/revoke":{"post":{"operationId":"devRevokeKey","summary":"Stop a key now","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"},{"name":"key_id","in":"path","required":true,"schema":{"type":"string"},"description":"key_…"}],"security":[{"developerSession":[]}],"tags":["Developer console"],"responses":{"204":{"description":"Revoked"},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/dev/apps/{app_id}/request-production":{"post":{"operationId":"devRequestProduction","summary":"Ask Prson to put this app in production (apps beyond the automatic one per person)","parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string"},"description":"app_…"}],"security":[{"developerSession":[]}],"tags":["Developer console"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason","contact_email"],"properties":{"reason":{"type":"string","minLength":20},"contact_email":{"type":"string"}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"production_request":{"type":"object","properties":{"id":{"type":"string"},"status":{"const":"pending"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"already_production or already_requested","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/topups":{"post":{"operationId":"topUp","summary":"Start a balance top-up (returns a Stripe Checkout URL)","description":"`amount_cents` is what your balance gets once paid. Checkout asks for the billing address and, for a business, its VAT number; VAT (reverse-charged for EU businesses with a valid VAT number) is added on top where it applies, and Stripe emails an invoice from Yumankind OÜ for each payment.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount_cents","currency"],"properties":{"amount_cents":{"type":"integer","minimum":2000,"maximum":5000000,"description":"credited to the balance, before tax; at least 2000 (20.00)"},"currency":{"type":"string"}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"topup":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/ledger":{"get":{"operationId":"getLedger","summary":"Balance movements, newest first","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"entries":{"type":"array","items":{"type":"object"}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/webhooks":{"get":{"operationId":"listWebhooks","summary":"Your webhook endpoints","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"endpoints":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"post":{"operationId":"createWebhook","summary":"Add a webhook endpoint (the signing secret is returned once)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"public https"},"events":{"type":"array","items":{"enum":["*","task.created","offers.dispatched","assignment.accepted","assignment.withdrawn","assignment.submitted","assignment.approved","assignment.rejected","task.completed","task.expired","task.cancelled","application.received","application.review_requested","stop.reported","stop.approved","stop.rejected","result.recorded","result.approved","result.rejected","verification.answered","verification.slot_verified","verification.slot_rejected","verification.completed","verification.expired","verification.cancelled"]}},"description":{"type":"string"}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"},"secret":{"type":"string"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/webhooks/{webhook_id}/test":{"post":{"operationId":"testWebhook","summary":"Send a ping delivery","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string"},"description":"whe_…"}],"responses":{"202":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/webhooks/{webhook_id}":{"patch":{"operationId":"updateWebhook","summary":"Change an endpoint's events or label, or disable it; re-enabling resets its failure count","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string"},"description":"whe_…"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"enum":["*","task.created","offers.dispatched","assignment.accepted","assignment.withdrawn","assignment.submitted","assignment.approved","assignment.rejected","task.completed","task.expired","task.cancelled","application.received","application.review_requested","stop.reported","stop.approved","stop.rejected","result.recorded","result.approved","result.rejected","verification.answered","verification.slot_verified","verification.slot_rejected","verification.completed","verification.expired","verification.cancelled"]}},"description":{"type":["string","null"]},"status":{"enum":["active","disabled"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"endpoint":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"delete":{"operationId":"deleteWebhook","summary":"Remove an endpoint and its delivery log","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string"},"description":"whe_…"}],"responses":{"204":{"description":"Removed"},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/webhooks/{webhook_id}/rotate-secret":{"post":{"operationId":"rotateWebhookSecret","summary":"A new signing secret, returned once; the old one stops at once","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string"},"description":"whe_…"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"secret":{"type":"string"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/webhooks/{webhook_id}/deliveries":{"get":{"operationId":"listWebhookDeliveries","summary":"The endpoint's last 50 deliveries, newest first","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string"},"description":"whe_…"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"deliveries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"event_id":{"type":"string"},"event_type":{"type":"string"},"status":{"type":"string"},"attempts":{"type":"integer"},"last_status":{"type":["integer","null"],"description":"your endpoint's HTTP status"},"last_error":{"type":["string","null"]},"created_at":{"type":"integer"},"delivered_at":{"type":["integer","null"]}}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/connected-apps":{"get":{"operationId":"listConnectedApps","summary":"Apps people connected to your organisation with OAuth (API key only, not a connected app)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"apps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"oag_…"},"client_id":{"type":"string"},"client_name":{"type":"string"},"client_uri":{"type":["string","null"]},"client_kind":{"type":"string"},"redirect_host":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"spend_cap_cents":{"type":["integer","null"]},"approved_by":{"type":["string","null"],"description":"the member who connected it"},"created_at":{"type":"integer"},"last_used_at":{"type":["integer","null"]}}}}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/org/connected-apps/{grant_id}":{"delete":{"operationId":"disconnectApp","summary":"Disconnect an app: its tokens stop working","parameters":[{"name":"grant_id","in":"path","required":true,"schema":{"type":"string"},"description":"oag_…"}],"responses":{"204":{"description":"Disconnected"},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/v1/notify":{"post":{"operationId":"sendNotification","summary":"Send a website notification to a person who opted in (scope notify:write)","description":"The person gave your site a `handle` when they signed in with Prson and ticked \"Let this site send you notifications\". It reaches their Prson app's inbox and, unless they muted your site, as a push. Plain text; `url` may only point at the site's own domain. The app's registered domains must cover the handle's domain. Each one takes a unit of the app's plan allowance, or 1 cent from the balance; sandbox apps send free (`test: true`). At most 3 a day per person and site, and a daily cap per app. API keys only, never an OAuth-connected app.","x-scopes":["notify:write"],"x-api-key-only":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["handle","title","body"],"additionalProperties":false,"properties":{"handle":{"type":"string","maxLength":100},"title":{"type":"string","description":"at most 60 characters"},"body":{"type":"string","description":"at most 180 characters"},"url":{"type":"string","maxLength":500,"description":"a link on the handle's domain"}}}}}},"responses":{"202":{"description":"Queued","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"const":"queued"},"domain":{"type":"string"},"charged":{"enum":["sandbox","allowance","balance"]},"test":{"type":"boolean","description":"sent from a sandbox app"}}}}}},"400":{"description":"Invalid request (issues lists each problem)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or unknown API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"allowance_exhausted, or insufficient_balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks notify:write, the app hasn't registered the domain (domain_not_registered), or sending is suspended (notifications_suspended)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown handle (handle_not_found)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The person turned your notifications off (handle_revoked): forget the handle","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"app_rate_limited or handle_rate_limited, or too many requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/coverage/cells":{"get":{"operationId":"coverageCells","summary":"People available per map cell in a viewport","description":"Counts are coarse (e.g. \"20+\") without an API key holding coverage:read, and below the privacy floor always.","security":[{"apiKey":[]},{}],"parameters":[{"name":"bbox","in":"query","required":true,"schema":{"type":"string"},"description":"west,south,east,north"},{"name":"skill","in":"query","schema":{"type":"string"}},{"name":"min_level","in":"query","schema":{"type":"integer","minimum":0,"maximum":6}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"resolution":{"type":"integer"},"cells":{"type":"array","items":{"allOf":[{"type":"object","properties":{"cell":{"type":"string"}}},{"type":"object","properties":{"count":{"type":["integer","null"]},"label":{"type":"string","example":"20+"}}}]}}}}}}},"400":{"description":"bad_bbox","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Too many cells: zoom in (bbox_too_large)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/coverage/world":{"get":{"operationId":"coverageWorld","summary":"People available across the planet, per large cell (for a zoomed-out globe)","security":[{"apiKey":[]},{}],"parameters":[{"name":"skill","in":"query","schema":{"type":"string"}},{"name":"min_level","in":"query","schema":{"type":"integer","minimum":0,"maximum":6}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"resolution":{"type":"integer"},"cells":{"type":"array","items":{"allOf":[{"type":"object","properties":{"cell":{"type":"string"}}},{"type":"object","properties":{"count":{"type":["integer","null"]},"label":{"type":"string","example":"20+"}}}]}}}}}}}}}},"/v1/catalog":{"get":{"operationId":"catalog","summary":"Skill codes for tasks and coverage, and the licensed professions per country","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"skills":{"type":"array","items":{"type":"object"}},"professions":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"authority":{"type":["string","null"]}}}}}}}}}}}}},"/v1/company/public-key":{"get":{"operationId":"companyPublicKey","summary":"Prson's keys for checking verdict signatures (by kid)","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"const":true},"publicKey":{"type":"string","description":"the active key, PEM"},"activeKid":{"type":"string"},"verificationKeys":{"type":"array","items":{"type":"object","properties":{"kid":{"type":"string"},"publicKey":{"type":"string","description":"PEM"},"status":{"type":"string"}}}},"issuedAt":{"type":"integer"},"expiresIn":{"type":"integer"}}}}}},"503":{"description":"The signing key isn't configured","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/config":{"get":{"operationId":"appConfig","summary":"The apps' configuration (feature switches, the update floor) and what this environment can verify","description":"`capabilities.phone_verification` and `capabilities.address_verification` are true only where this environment is set up for them (Firebase phone sign-in; letters posted by Pingen) and the operators' feature switch is on. The app offers adding or verifying a phone or address only when they're true.","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"features":{"type":"object","additionalProperties":{"type":"boolean"}},"capabilities":{"type":"object","properties":{"phone_verification":{"type":"boolean"},"address_verification":{"type":"boolean"}}}},"additionalProperties":true}}}}}}},"/v1/early-access/withdraw":{"post":{"operationId":"withdrawEarlyAccess","summary":"Take an address off the app's early-access list","description":"No sign-in. The answer is the same whether or not the address was on the list. Addresses are otherwise kept 12 months after the last request.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"Not on the list (any more)","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"const":true}}}}}},"400":{"description":"Not an email address (invalid_email)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/TooManyRequests"}}}}},"components":{"responses":{"TooManyRequests":{"description":"Too many requests (too_many_requests, or the route's own limit named in error): wait and retry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"prs_live_… (prs_test_… outside production; prs_sandbox_… for a sandbox app's keys)"},"developerSession":{"type":"http","scheme":"bearer","description":"prs_ds_…: a developer console session from POST /v1/dev/sign-in (12 hours). Only /v1/dev/*, POST /v1/org/topups, GET /v1/org/ledger and /v1/org/apps/{app_id}/plan/… take it."}},"schemas":{"CreateTask":{"type":"object","properties":{"title":{"type":"string","minLength":3,"maxLength":140},"instructions":{"type":"string","minLength":10,"maxLength":5000},"mode":{"type":"string","enum":["in_person","remote"]},"location":{"type":"object","properties":{"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180},"address":{"type":"string","maxLength":300}},"required":["lat","lng"]},"country":{"type":"string","pattern":"^[A-Z]{2}$"},"starts_at":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}]},"due_at":{"anyOf":[{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"}]},"slots":{"default":1,"type":"integer","minimum":1,"maximum":500},"pay_per_slot":{"type":"object","properties":{"amount_cents":{"type":"integer","minimum":100,"maximum":10000000},"currency":{"type":"string","pattern":"^[A-Z]{3}$"}},"required":["amount_cents","currency"]},"required_skills":{"default":[],"maxItems":10,"type":"array","items":{"type":"string","pattern":"^[a-z0-9_]{2,48}$"}},"required_license":{"type":"object","properties":{"code":{"type":"string","pattern":"^[a-z0-9_]{2,48}$"},"country":{"type":"string","pattern":"^[A-Z]{2}$"}},"required":["code"]},"required_languages":{"default":[],"maxItems":10,"type":"array","items":{"type":"string","pattern":"^[a-z]{2}$"}},"min_verification_level":{"default":0,"type":"integer","minimum":0,"maximum":6},"proof":{"default":{"photos_min":1,"max_distance_m":300},"type":"object","properties":{"photos_min":{"default":1,"type":"integer","minimum":0,"maximum":20},"require_location":{"type":"boolean"},"max_distance_m":{"default":300,"type":"integer","minimum":25,"maximum":50000}}},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"stops":{"maxItems":200,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":140},"address":{"type":"string","maxLength":300},"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180},"instructions":{"type":"string","maxLength":1000}},"required":["name"]}},"pay_per_stop":{"type":"object","properties":{"amount_cents":{"type":"integer","minimum":100,"maximum":1000000}},"required":["amount_cents"]},"pay_by_country":{"type":"object","propertyNames":{"type":"string","pattern":"^[A-Z]{2}$"},"additionalProperties":{"type":"object","properties":{"per_slot_cents":{"type":"integer","minimum":100,"maximum":10000000},"per_stop_cents":{"type":"integer","minimum":100,"maximum":1000000},"per_result_cents":{"type":"integer","minimum":100,"maximum":1000000}},"required":["per_slot_cents"]}},"local_pay":{"type":"object","properties":{"reference_country":{"type":"string","pattern":"^[A-Z]{2}$"},"countries":{"minItems":1,"maxItems":250,"type":"array","items":{"type":"string","pattern":"^[A-Z]{2}$"}}},"required":["reference_country"]},"pay_per_result":{"type":"object","properties":{"amount_cents":{"type":"integer","minimum":100,"maximum":1000000},"max_results":{"type":"integer","minimum":1,"maximum":10000},"label":{"type":"string","minLength":1,"maxLength":40},"landing_url":{"type":"string","maxLength":1000,"format":"uri"},"window_days":{"default":30,"type":"integer","minimum":1,"maximum":365}},"required":["amount_cents","max_results"]},"screening":{"type":"object","properties":{"kind":{"default":"video","type":"string","enum":["video","voice_interview"]},"prompt":{"type":"string","minLength":10,"maxLength":500},"max_seconds":{"default":60,"type":"integer","minimum":15,"maximum":180},"questions":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"string","minLength":5,"maxLength":300}},"rubric":{"type":"string","minLength":10,"maxLength":2000},"follow_ups":{"type":"boolean"},"pass_score":{"type":"integer","minimum":0,"maximum":100}}}},"required":["title","instructions","mode","due_at","pay_per_slot"]},"CreateVerification":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"requirements":{"minItems":1,"maxItems":10,"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["fact","property","selfie","document","selfie_with_document","photo","video","document_signature"]},"name":{"type":"string","minLength":1,"maxLength":80},"description":{"type":"string","maxLength":300},"optional":{"type":"boolean"},"fact":{"type":"string","minLength":1,"maxLength":64},"property":{"type":"string","minLength":1,"maxLength":40},"reveal_value":{"type":"boolean"},"document_types":{"minItems":1,"maxItems":2,"type":"array","items":{"type":"string","enum":["passport","national_id"]}},"issuing_countries":{"minItems":1,"maxItems":60,"type":"array","items":{"type":"string","pattern":"^[A-Z]{3}$"}},"require_location":{"type":"boolean"},"require_document_verification":{"type":"boolean"},"required_facts":{"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":64}},"min_photos":{"type":"integer","minimum":1,"maximum":9007199254740991},"document_id":{"type":"string","pattern":"^vdoc_[A-Za-z0-9_-]{8,64}$"},"signature_position":{"type":"object","properties":{"page":{"type":"integer","minimum":1,"maximum":9007199254740991},"x":{"type":"number","minimum":0},"y":{"type":"number","minimum":0},"width":{"type":"number","minimum":20,"maximum":2000},"height":{"type":"number","minimum":10,"maximum":2000}},"required":["page","x","y","width","height"],"additionalProperties":false},"min_level":{"anyOf":[{"type":"number","const":5},{"type":"number","const":6}]}},"required":["type"],"additionalProperties":false}},"min_verification_level":{"type":"integer","minimum":0,"maximum":6},"allowed_identity_types":{"minItems":1,"maxItems":2,"type":"array","items":{"type":"string","enum":["personal","organization"]}},"expires_in_hours":{"default":72,"type":"integer","minimum":1,"maximum":168},"external_ref":{"type":"string","minLength":1,"maxLength":200},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"currency":{"type":"string","pattern":"^[A-Z]{3}$"}},"required":["title","requirements"],"additionalProperties":false},"Requirement":{"type":"object","description":"A requirement as returned (slot_id identifies it in responses).","properties":{"slot_id":{"type":"string"},"type":{"enum":["fact","property","selfie","document","selfie_with_document","photo","video"]},"name":{"type":"string"},"description":{"type":["string","null"]},"optional":{"type":"boolean"},"fact":{"type":"string"},"property":{"type":"string"},"reveal_value":{"type":"boolean"},"document_types":{"type":"array","items":{"enum":["passport","national_id"]}},"issuing_countries":{"type":"array","items":{"type":"string"}},"require_location":{"type":"boolean"},"require_document_verification":{"type":"boolean"},"required_facts":{"type":"array","items":{"type":"string"}}}},"VerificationResponse":{"type":"object","description":"One answer. Only what the person chose to share, checked by Prson.","properties":{"respondent_id":{"type":"string","description":"rsp_…: the person, pairwise for your organisation"},"slot_id":{"type":"string"},"requirement_name":{"type":"string"},"type":{"type":"string"},"status":{"enum":["uploaded","verified","rejected"]},"verdict_level":{"enum":["strong","weak","failed",null]},"answered_at":{"type":"integer"},"verified_at":{"type":["integer","null"]},"fact":{"type":"object","properties":{"id":{"type":"string"},"value":{"type":"boolean"},"description":{"type":["string","null"]},"expires_at":{"type":["string","null"]}}},"property":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":["string","null"]},"value_disclosed":{"type":"boolean"},"verified_at":{"type":["string","null"]},"expires_at":{"type":["string","null"]}}},"document":{"type":"object","properties":{"document_type":{"type":"string"},"issuing_country":{"type":"string"},"expires_on":{"type":["string","null"]},"verification_level":{"type":["integer","null"]},"facts":{"type":"array","items":{"type":"object"}}}},"location":{"type":"object","description":"only when the requirement asked for location","properties":{"lat":{"type":"number"},"lng":{"type":"number"},"accuracy_m":{"type":["number","null"]}}},"checks":{"type":"object","description":"captures: device attestation level, motion and network-location consistency"},"proof_id":{"type":"string"},"files":{"type":"array","items":{"enum":["photo","video","sensors"]}},"verdict_signature":{"type":["object","null"],"properties":{"envelope":{"type":"object"},"signature":{"type":"string"},"kid":{"type":"string"}}},"verdict_disclosures":{"type":"array","description":"The disclosed values as the signed envelope's `disclosures` commit to them: [salt, kind, id, value]. digest = base64url(SHA-256(canonical JSON of the array)). Empty for captures.","items":{"type":"array","minItems":4,"maxItems":4,"prefixItems":[{"type":"string"},{"enum":["fact","property","document_field"]},{"type":"string"},{"type":["string","boolean","number"]}]}}}},"Verification":{"type":"object","properties":{"id":{"type":"string"},"status":{"enum":["open","partially_fulfilled","fulfilled","cancelled","expired"],"description":"fulfilled: one person verified every required (non-optional) requirement"},"title":{"type":"string"},"requirements":{"type":"array","items":{"$ref":"#/components/schemas/Requirement"}},"min_verification_level":{"type":"integer"},"allowed_identity_types":{"type":"array","items":{"type":"string"}},"created_at":{"type":"integer"},"expires_at":{"type":"integer"},"completed_at":{"type":["integer","null"]},"cancelled_at":{"type":["integer","null"]},"share_url":{"type":"string"},"external_ref":{"type":["string","null"]},"metadata":{"type":["object","null"]},"charge":{"type":"object","properties":{"currency":{"type":"string"},"reserved_cents":{"type":"integer"},"spent_cents":{"type":"integer"},"allowance":{"type":"object","description":"a free plan's allowance paid for the base, ID chip and signature prices","properties":{"plan":{"type":"string"},"period":{"type":"string"},"covered_cents":{"type":"integer"}}},"discount":{"type":"object","description":"the launch or volume discount this verification was created with (base, ID chip and signature prices; never premiums)","properties":{"kind":{"enum":["launch","volume"]},"percent":{"type":"integer"},"regular_cents":{"type":"integer","description":"the price without the discount"},"until":{"type":"string","description":"launch: its last day (UTC)","example":"2027-03-31"},"ends_at":{"type":"integer","description":"launch: when it ends, Unix ms"}}}}},"responses":{"type":"array","items":{"$ref":"#/components/schemas/VerificationResponse"},"description":"GET one; lists have response_count and respondent_count instead. Kept 30 days past expiry."}}},"Money":{"type":"object","required":["amount_cents","currency"],"properties":{"amount_cents":{"type":"integer"},"currency":{"type":"string","example":"USD"}}},"Task":{"type":"object","properties":{"id":{"type":"string"},"status":{"enum":["open","filled","completed","cancelled","expired"]},"title":{"type":"string"},"instructions":{"type":"string"},"mode":{"enum":["in_person","remote"]},"location":{"type":["object","null"],"properties":{"lat":{"type":"number"},"lng":{"type":"number"},"address":{"type":["string","null"]}}},"due_at":{"type":"integer","description":"epoch ms"},"slots":{"type":"integer"},"pay_per_slot":{"$ref":"#/components/schemas/Money","description":"with pay by country: the highest country amount (what was reserved)"},"pay_by_country":{"type":["object","null"],"description":"country → amounts, the resolved table (with local_pay, the scaled amounts)","additionalProperties":{"type":"object","properties":{"per_slot_cents":{"type":"integer"},"per_stop_cents":{"type":"integer"},"per_result_cents":{"type":"integer"}}}},"local_pay":{"type":["object","null"],"properties":{"reference_country":{"type":"string"},"countries":{"type":"array","items":{"type":"string"}}}},"pay_per_result":{"type":["object","null"],"properties":{"amount_cents":{"type":"integer"},"currency":{"type":"string"},"max_results":{"type":"integer"},"label":{"type":["string","null"]},"landing_url":{"type":["string","null"]},"window_days":{"type":"integer"}}},"platform_fee":{"$ref":"#/components/schemas/Money"},"total":{"$ref":"#/components/schemas/Money","description":"everything reserved: pay, stops, results and the fee"},"min_verification_level":{"type":"integer","description":"0 anyone, 5 identity verified from a passport/ID chip"},"proof":{"type":"object","properties":{"photos_min":{"type":"integer"},"require_location":{"type":"boolean"},"max_distance_m":{"type":"integer"}}},"review_status":{"enum":["ok","held","removed"],"description":"held: waiting for a content-policy check, offered to nobody; removed: taken down"},"metadata":{"type":["object","null"]},"created_at":{"type":"integer"},"updated_at":{"type":"integer"}}},"Assignment":{"type":"object","properties":{"id":{"type":"string"},"status":{"enum":["active","submitted","approved","rejected","cancelled"]},"agent":{"type":"object","properties":{"display_name":{"type":["string","null"]},"verification_level":{"type":"integer"}}},"pay":{"$ref":"#/components/schemas/Money"},"pay_country":{"type":["string","null"],"description":"the country whose rates this person was hired at"},"result":{"type":["object","null"],"properties":{"code":{"type":"string"},"link":{"type":["string","null"]}},"description":"pay-per-result tasks: this person's code"},"proofs":{"type":"array","items":{"$ref":"#/components/schemas/Proof"}}}},"Application":{"type":"object","properties":{"id":{"type":"string"},"status":{"enum":["pending","accepted","rejected","withdrawn","closed"]},"kind":{"enum":["video","voice_interview"]},"display_name":{"type":["string","null"]},"verification_level":{"type":"integer"},"decision_note":{"type":["string","null"]},"pay":{"type":["object","null"],"properties":{"amount_cents":{"type":"integer"},"currency":{"type":"string"}},"description":"the rate this person would be hired at"},"video_url":{"type":["string","null"],"description":"null for interviews and for videos deleted after 90 days"},"review_request":{"type":["object","null"],"properties":{"requested_at":{"type":"integer"},"note":{"type":["string","null"]}},"description":"the applicant asked for a person to review their AI-scored interview"},"human_reviewed":{"type":["boolean","null"],"description":"the decision was confirmed as a person's (required through MCP for interviews)"},"interview":{"type":["object","null"],"properties":{"score":{"type":"integer","minimum":0,"maximum":100,"description":"advisory: an AI scored it; a person must review the interview and decide"},"score_advisory":{"type":"string"},"summary":{"type":"string"},"strengths":{"type":"array","items":{"type":"string"}},"concerns":{"type":"array","items":{"type":"string"}},"per_question":{"type":"array","items":{"type":"object","properties":{"question_index":{"type":"integer"},"notes":{"type":"string"}}}},"language":{"type":"string","description":"the language the person answered in"},"transcript":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"kind":{"enum":["question","follow_up"]},"question":{"type":"string"},"asked":{"type":"string","description":"the question as asked, in the person's language"},"answer_text":{"type":"string"},"answer_translated":{"type":["string","null"]},"audio_url":{"type":["string","null"]},"seconds":{"type":["number","null"]}}}}}},"created_at":{"type":"integer"},"decided_at":{"type":["integer","null"]}}},"Result":{"type":"object","properties":{"id":{"type":"string"},"assignment_id":{"type":"string"},"source":{"enum":["requester","agent","stop"],"description":"who recorded it: you, the person, or a stop reported as signed up"},"external_ref":{"type":["string","null"]},"value_cents":{"type":["integer","null"]},"occurred_at":{"type":["integer","null"]},"note":{"type":["string","null"]},"proof_ids":{"type":"array","items":{"type":"string"}},"stop_id":{"type":["string","null"]},"status":{"enum":["pending","approved","rejected"]},"pay":{"$ref":"#/components/schemas/Money"},"payout_status":{"type":"string"},"created_at":{"type":"integer"},"decided_at":{"type":["integer","null"]},"decision_note":{"type":["string","null"]}}},"Proof":{"type":"object","properties":{"id":{"type":"string"},"content_type":{"type":"string"},"url":{"type":"string","description":"GET with your API key"},"verification":{"enum":["attested","unverified"],"description":"attested: captured and signed by the person's Prson app; unverified: uploaded from a browser"},"device_attestation":{"enum":["none","basic","strong",null],"description":"how genuine the capturing phone proved to be"},"distance_m":{"type":["integer","null"]},"location_ok":{"type":["boolean","null"]},"location_note":{"type":["string","null"],"description":"why the location didn't count: too_far, mock_location, impossible_speed, poor_accuracy, …"},"captured_at":{"type":["integer","null"]}}},"Balance":{"type":"object","properties":{"currency":{"type":"string"},"available_cents":{"type":"integer"},"reserved_cents":{"type":"integer"}}},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"status":{"enum":["active","disabled"]},"consecutive_failures":{"type":"integer"}}},"Webhook":{"type":"object","description":"POSTed to your endpoint. Headers: Prson-Event-Id (idempotency key) and Prson-Signature: t={unix seconds},v1={hex HMAC-SHA256(secret, \"{t}.{raw body}\")}. Reply 2xx within 10 s; failures are retried with backoff for about a day.","properties":{"id":{"type":"string"},"type":{"enum":["task.created","offers.dispatched","assignment.accepted","assignment.withdrawn","assignment.submitted","assignment.approved","assignment.rejected","task.completed","task.expired","task.cancelled","application.received","application.review_requested","stop.reported","stop.approved","stop.rejected","result.recorded","result.approved","result.rejected","verification.answered","verification.slot_verified","verification.slot_rejected","verification.completed","verification.expired","verification.cancelled","ping"]},"created_at":{"type":"integer"},"api_version":{"const":"2026-10-01"},"data":{"type":"object","description":"Task events: task (and ids). Verification events: verification (as GET returns it, at the time of the event) and, for answered / slot_verified / slot_rejected, the response; completed adds respondent_id (who completed it first); expired keeps status fulfilled if it was.","properties":{"task":{"$ref":"#/components/schemas/Task"},"assignment_id":{"type":"string"},"verification":{"$ref":"#/components/schemas/Verification"},"response":{"$ref":"#/components/schemas/VerificationResponse"},"respondent_id":{"type":"string"}}}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}},"servers":[{"url":"https://api.prson.net"}]}