{"openapi":"3.1.0","info":{"title":"Stood platform API","version":"1.5.0","summary":"Milestone payments held on PayPal (sandbox) and released only on evidence","description":"Every request carries the platform key (Authorization: Bearer) and a Stood-Signature: t=<unix seconds>,v2=<hex HMAC-SHA256 over the canonical request>, within five minutes. Bodies are at most 64 KiB. Each platform may make 120 writes and 600 reads a minute; over that, or after 30 failed sign-ins from one address in a minute, Stood answers 429 with Retry-After. Stood only talks to the PayPal sandbox.","contact":{"name":"Maku Mazakpe","email":"makpalyy@gmail.com","url":"https://startuptribunal.com/maku"},"license":{"name":"MIT","identifier":"MIT"}},"servers":[{"url":"https://stood-api.onrender.com/v1","description":"Hosted (PayPal sandbox)"}],"paths":{"/allowances":{"post":{"operationId":"createAllowance","summary":"Draft an allowance: a payment cap split into milestones, each with an evidence profile","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Same key and body return the same response; a different body is 409","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllowanceDraft"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Allowance"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency or version conflict","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KiB","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/allowances/{id}":{"get":{"operationId":"getAllowance","summary":"Read the original allowance draft this platform owns; use versions/current for amended terms","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Allowance"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/allowances/{id}/versions":{"post":{"operationId":"proposeAllowanceVersion","summary":"Propose immutable evidence terms for unreserved work; financial boundaries stay fixed","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Same key and body return the same response; a different body is 409","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllowanceProposal"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllowanceVersion"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency or version conflict","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KiB","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/allowances/{id}/versions/{version}":{"get":{"operationId":"getAllowanceVersion","summary":"Read an immutable terms version, or use current for the latest version","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllowanceVersion"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/allowances/{id}/versions/{version}/mandate":{"post":{"operationId":"requestVersionMandate","summary":"Start saved-PayPal signing for an explicit terms version (send {})","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"version","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Same key and body return the same response; a different body is 409","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted (recorded, not yet done)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Mandate"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency or version conflict","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KiB","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/allowances/{id}/mandate":{"post":{"operationId":"requestMandate","summary":"Start version-one signing (send {}); amended terms require the explicit version signing route","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Same key and body return the same response; a different body is 409","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"202":{"description":"Accepted (recorded, not yet done)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Mandate"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency or version conflict","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KiB","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/allowances/{id}/mandate/{key}":{"get":{"operationId":"getMandate","summary":"Read signing status and, while awaiting the buyer, the approval link","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Mandate"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/baselines":{"post":{"operationId":"requestBaseline","summary":"Ask Stood to run one milestone's frozen tests on its base commit (a red baseline proves new work is needed)","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Same key and body return the same response; a different body is 409","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeTermsInput"}}}},"responses":{"202":{"description":"Accepted (recorded, not yet done)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Baseline"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency or version conflict","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KiB","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/baselines/{id}":{"get":{"operationId":"getBaseline","summary":"Read a baseline: queued, or each frozen test as it ran on the base commit","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Baseline"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tranches/{id}":{"get":{"operationId":"getTranche","summary":"Read a tranche: state, hold, latest decision and plain-language sentences","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tranche"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tranches/{id}/funding":{"post":{"operationId":"requestFunding","summary":"Reserve funding (a PayPal authorization hold) for a tranche at the version just read","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Same key and body return the same response; a different body is 409","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FundingRequest"}}}},"responses":{"202":{"description":"Accepted (recorded, not yet done)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Funding"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency or version conflict","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KiB","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tranches/{id}/funding/{key}":{"get":{"operationId":"getFunding","summary":"Read funding status, the approval link when required, and the hold expiry","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"key","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Funding"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tranches/{id}/uploads":{"post":{"operationId":"createUpload","summary":"Reserve a bounded site-visit photo upload session; returns temporary write-once URLs","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Same key and body keep the same upload session and expiry; current URLs and status are derived on each read. A different body is 409.","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadInput"}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSession"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency or version conflict","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KiB","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tranches/{id}/uploads/{uploadId}":{"get":{"operationId":"getUpload","summary":"Read an owned upload session and current upload URLs until expiry","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"uploadId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSession"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tranches/{id}/uploads/{uploadId}/complete":{"post":{"operationId":"completeUpload","summary":"Check the uploaded bytes and complete the evidence intake; creates no decision or payment","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"uploadId","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Same key and body return the same response; a different body is 409","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadCompletion"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadSession"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency or version conflict","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KiB","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tranches/{id}/packages":{"post":{"operationId":"submitPackage","summary":"Submit a commit package for Stood's runner to judge; returns QUEUED, never a result","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Same key and body return the same response; a different body is 409","schema":{"type":"string","maxLength":200}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitPackageInput"}}}},"responses":{"202":{"description":"Accepted (recorded, not yet done)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitPackage"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Idempotency or version conflict","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KiB","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tranches/{id}/usage":{"post":{"operationId":"confirmUsage","summary":"Forward the buyer's signed confirmation that a final milestone is in use; the runner then decides it again","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageReceipt"}}}},"responses":{"202":{"description":"Accepted (recorded, not yet done)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageAcceptance"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KiB","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Invalid request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tranches/{id}/packages/{packageId}":{"get":{"operationId":"getPackage","summary":"Read a submitted commit package","security":[{"platformKey":[],"requestSignature":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"packageId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommitPackage"}}}},"401":{"description":"Missing or invalid platform key or signature","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not found, or not owned by this platform","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Too many requests: over the platform's per-minute budget (120 writes, 600 reads) or too many failed sign-ins from this address","headers":{"Retry-After":{"description":"Seconds until the current one-minute window ends","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Storage or the feature is unavailable; retry with the same idempotency key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"components":{"schemas":{"Allowance":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":200},"status":{"type":"string","const":"DRAFT"},"payee_ref":{"type":"string"},"cap":{"$ref":"#/components/schemas/Money"},"milestones":{"type":"array","items":{"$ref":"#/components/schemas/Milestone"}},"window_days":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"max_resubmits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"tranches":{"type":"array","items":{"$ref":"#/components/schemas/TrancheRef"}}},"required":["id","status","payee_ref","cap","milestones","window_days","max_resubmits","tranches"],"additionalProperties":false},"AllowanceDraft":{"type":"object","properties":{"payee_ref":{"type":"string","minLength":1,"maxLength":200},"cap":{"$ref":"#/components/schemas/Money"},"milestones":{"maxItems":50,"type":"array","items":{"$ref":"#/components/schemas/Milestone"}},"window_days":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"max_resubmits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["payee_ref","cap","milestones","window_days","max_resubmits"],"additionalProperties":false},"AllowanceProposal":{"type":"object","properties":{"expected_version":{"type":"integer","minimum":1,"maximum":2147483646},"terms":{"$ref":"#/components/schemas/AllowanceDraft"}},"required":["expected_version","terms"],"additionalProperties":false},"AllowanceVersion":{"type":"object","properties":{"version":{"type":"integer","minimum":1,"maximum":2147483647},"body":{"$ref":"#/components/schemas/Allowance"},"terms_hash":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["version","body","terms_hash"],"additionalProperties":false},"Baseline":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":200},"status":{"$ref":"#/components/schemas/BaselineStatus"},"repository":{"type":"string"},"base_commit":{"type":"string","pattern":"^[a-f0-9]{40}$"},"test_bundle_hash":{"type":"string","pattern":"^[a-f0-9]{64}$"},"tests":{"description":"Only when DONE: every frozen test as it ran on the base commit; a red baseline is all FAIL","type":["array","null"],"items":{"$ref":"#/components/schemas/BaselineTest"}},"evidence_sha256":{"description":"Only when DONE: SHA-256 of the run stored in Stood's evidence bucket","type":["string","null"],"pattern":"^[a-f0-9]{64}$"},"created_at":{"type":"string","description":"UTC ISO-8601 timestamp"},"finished_at":{"type":["string","null"],"description":"UTC ISO-8601 timestamp"}},"required":["id","status","repository","base_commit","test_bundle_hash","tests","evidence_sha256","created_at","finished_at"],"additionalProperties":false},"BaselineStatus":{"type":"string","enum":["QUEUED","DONE","INVALID"],"description":"QUEUED until Stood has run it; INVALID when the frozen tests are not at the base commit as described"},"BaselineTest":{"type":"object","properties":{"id":{"type":"string"},"status":{"$ref":"#/components/schemas/BaselineTestStatus"}},"required":["id","status"],"additionalProperties":false},"BaselineTestStatus":{"type":"string","enum":["PASS","FAIL"]},"CodeTerms":{"type":"object","properties":{"repository":{"type":"string","pattern":"^[A-Za-z0-9-]{1,39}\\/[A-Za-z0-9_.-]{1,100}$"},"baseCommit":{"type":"string","pattern":"^[a-f0-9]{40}$"},"testBundleHash":{"type":"string","pattern":"^[a-f0-9]{64}$"},"manifestHash":{"type":"string","pattern":"^[a-f0-9]{64}$"},"testIds":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"string"}},"tests":{"minItems":1,"maxItems":200,"type":"array","items":{"$ref":"#/components/schemas/FrozenTest"}},"minMutation":{"type":"number","minimum":0,"maximum":1}},"required":["repository","baseCommit","testBundleHash","manifestHash","testIds","tests","minMutation"],"additionalProperties":false,"description":"Frozen terms of a code milestone (profiles code.*), checked at draft time."},"CodeTermsInput":{"type":"object","properties":{"repository":{"type":"string","pattern":"^[A-Za-z0-9-]{1,39}\\/[A-Za-z0-9_.-]{1,100}$"},"baseCommit":{"type":"string","pattern":"^[a-f0-9]{40}$"},"testBundleHash":{"type":"string","pattern":"^[a-f0-9]{64}$"},"manifestHash":{"type":"string","pattern":"^[a-f0-9]{64}$"},"testIds":{"minItems":1,"maxItems":200,"type":"array","items":{"type":"string"}},"tests":{"minItems":1,"maxItems":200,"type":"array","items":{"$ref":"#/components/schemas/FrozenTest"}},"minMutation":{"description":"Mutation-score floor from 0 to 1; no floor (0) when omitted","type":"number","minimum":0,"maximum":1}},"required":["repository","baseCommit","testBundleHash","manifestHash","testIds","tests"],"additionalProperties":false,"description":"Frozen terms of a code milestone, as a platform sends them."},"CommitPackage":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":200},"trancheId":{"type":"string","minLength":1,"maxLength":200},"status":{"type":"string","const":"QUEUED"},"waitingFor":{"$ref":"#/components/schemas/PackageWaitingFor"},"metadata":{"$ref":"#/components/schemas/CommitPackageInput"},"createdAt":{"type":"string","description":"UTC ISO-8601 timestamp"}},"required":["id","trancheId","status","waitingFor","metadata","createdAt"],"additionalProperties":false},"CommitPackageInput":{"type":"object","properties":{"repository":{"type":"string","pattern":"^[A-Za-z0-9_-]+\\/[A-Za-z0-9_.-]+$"},"base_commit":{"type":"string","pattern":"^[a-f0-9]{40}$"},"commit_sha":{"type":"string","pattern":"^[a-f0-9]{40}$"},"report_ref":{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9/_-]*\\.json$"},"report_sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["repository","base_commit","commit_sha","report_ref","report_sha256"],"additionalProperties":false},"Decision":{"type":"object","properties":{"outcome":{"$ref":"#/components/schemas/DecisionOutcome"},"effect":{"$ref":"#/components/schemas/PaymentEffect"},"profileId":{"type":"string"},"ruleSetVersion":{"type":"string"},"namedField":{"type":["string","null"]},"reason":{"type":"string"},"detail":{}},"required":["outcome","effect","profileId","ruleSetVersion","namedField","reason","detail"],"additionalProperties":{}},"DecisionOutcome":{"type":"string","enum":["RELEASE","REFUSE","WAIT"]},"FrozenTest":{"type":"object","properties":{"id":{"type":"string"},"path":{"type":"string"}},"required":["id","path"],"additionalProperties":false},"Funding":{"type":"object","properties":{"key":{"type":"string"},"status":{"$ref":"#/components/schemas/FundingStatus"},"approve_url":{"type":["string","null"]},"hold_expires_at":{"description":"Only while HELD: when the hold lapses, Unix milliseconds","type":["integer","null"],"minimum":-9007199254740991,"maximum":9007199254740991}},"required":["key","status","approve_url","hold_expires_at"],"additionalProperties":false},"FundingRequest":{"type":"object","properties":{"expected_version":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"The tranche version just read"},"nonce":{"type":"string","pattern":"^[A-HJ-NP-Z2-9]{3}$"}},"required":["expected_version","nonce"],"additionalProperties":false},"FundingStatus":{"type":"string","enum":["RESERVED","CREATING","AWAITING_APPROVAL","AUTHORIZING","HELD","FAILED","EXPIRED"]},"Mandate":{"type":"object","properties":{"key":{"type":"string"},"status":{"$ref":"#/components/schemas/MandateStatus"},"approve_url":{"description":"Only while AWAITING_APPROVAL: where the buyer approves","type":["string","null"]},"expires_at":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"When the signing request lapses, Unix milliseconds"}},"required":["key","status","approve_url","expires_at"],"additionalProperties":false},"MandateStatus":{"type":"string","enum":["RESERVED","CREATING","AWAITING_APPROVAL","TOKENIZING","SIGNED","REVOKED"]},"Milestone":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"amount":{"$ref":"#/components/schemas/Money"},"profile":{"type":"string","minLength":1,"maxLength":100,"description":"Evidence profile, e.g. code.milestone@1 or code.final@1"},"params":{"description":"CodeTerms for code.* profiles (checked); other profiles take their own parameters","anyOf":[{"$ref":"#/components/schemas/CodeTerms"},{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}]}},"required":["name","amount","profile"],"additionalProperties":false},"Money":{"type":"object","properties":{"minor":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Amount in minor units (cents)"},"currency":{"type":"string","minLength":3,"maxLength":3}},"required":["minor","currency"],"additionalProperties":false},"PackageWaitingFor":{"type":"string","enum":["HOLD","RENEWAL","RUNNER"]},"PaymentEffect":{"type":"string","enum":["CAPTURE","VOID","NONE","REVIEW"]},"PaymentProvider":{"type":"string","enum":["paypal-sandbox","simulator"]},"PendingPaymentOperation":{"type":"object","properties":{"effect":{"type":"string"},"status":{"type":"string"},"created_at":{"type":"string","description":"UTC ISO-8601 timestamp"}},"required":["effect","status","created_at"],"additionalProperties":false},"PhotoContentType":{"type":"string","enum":["image/jpeg","image/heic","image/webp"]},"Problem":{"type":"object","properties":{"type":{"type":"string","description":"urn:stood:problem:<code>"},"title":{"type":"string"},"status":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"code":{"type":"string"},"detail":{"type":"string"}},"required":["type","title","status","code","detail"],"additionalProperties":false,"description":"RFC 9457 problem details"},"Settlement":{"type":"object","properties":{"effect":{"type":"string"}},"required":["effect"],"additionalProperties":{}},"SignedUpload":{"type":"object","properties":{"key":{"type":"string"},"url":{"type":"string","format":"uri"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"}}},"required":["key","url","headers"],"additionalProperties":false},"StoredUploadPhoto":{"type":"object","properties":{"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"bytes":{"type":"integer","minimum":1,"maximum":8388608},"contentType":{"$ref":"#/components/schemas/PhotoContentType"},"key":{"type":"string"}},"required":["sha256","bytes","contentType","key"],"additionalProperties":false},"Tranche":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":200},"state":{"$ref":"#/components/schemas/TrancheState"},"version":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Send as expected_version when funding"},"profile":{"type":"string"},"amount":{"$ref":"#/components/schemas/Money"},"decision":{"oneOf":[{"$ref":"#/components/schemas/Decision"},{"type":"null"}]},"hold":{"oneOf":[{"$ref":"#/components/schemas/TrancheHold"},{"type":"null"}]},"settlement":{"oneOf":[{"$ref":"#/components/schemas/Settlement"},{"type":"null"}]},"safe_recovery":{"type":"boolean"},"pending":{"oneOf":[{"$ref":"#/components/schemas/PendingPaymentOperation"},{"type":"null"}]},"sentences":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{},"description":"Plain-language status for the payer and the inspector"},"package_id":{"type":["string","null"],"minLength":1,"maxLength":200},"resubmissions_left":{"type":"integer","minimum":0,"maximum":9007199254740991},"provider":{"$ref":"#/components/schemas/PaymentProvider"}},"required":["id","state","version","profile","amount","decision","hold","settlement","safe_recovery","pending","sentences","package_id","resubmissions_left","provider"],"additionalProperties":false},"TrancheHold":{"type":"object","properties":{"age_seconds":{"type":"integer","minimum":0,"maximum":9007199254740991},"expires_at":{"type":"string","description":"UTC ISO-8601 timestamp"}},"required":["age_seconds","expires_at"],"additionalProperties":false},"TrancheRef":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":200},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"TrancheState":{"type":"string","enum":["PENDING","WAIT_FUNDING","HELD","DECIDING","WAITING","CAPTURE_PENDING","VOID_PENDING","REAUTHORIZE_PENDING","RELEASED","REFUSED","EXPIRED","CANCELLED","DISPUTED"]},"UploadCompletion":{"type":"object","properties":{},"additionalProperties":false},"UploadInput":{"type":"object","properties":{"photos":{"minItems":1,"maxItems":10,"type":"array","items":{"$ref":"#/components/schemas/UploadPhoto"}}},"required":["photos"],"additionalProperties":false},"UploadPhoto":{"type":"object","properties":{"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"bytes":{"type":"integer","minimum":1,"maximum":8388608},"contentType":{"$ref":"#/components/schemas/PhotoContentType"}},"required":["sha256","bytes","contentType"],"additionalProperties":false},"UploadSession":{"type":"object","properties":{"id":{"type":"string","minLength":1,"maxLength":200},"trancheId":{"type":"string","minLength":1,"maxLength":200},"status":{"$ref":"#/components/schemas/UploadStatus"},"photos":{"minItems":1,"maxItems":10,"type":"array","items":{"$ref":"#/components/schemas/StoredUploadPhoto"}},"expiresAt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"completedAt":{"type":["integer","null"],"minimum":-9007199254740991,"maximum":9007199254740991},"uploads":{"maxItems":10,"type":"array","items":{"$ref":"#/components/schemas/SignedUpload"}}},"required":["id","trancheId","status","photos","expiresAt","completedAt","uploads"],"additionalProperties":false,"description":"COMPLETE means owned bytes, size, hash and format header checked; no assessment or payment. URLs are derived short-lived capabilities, not persisted receipts."},"UploadStatus":{"type":"string","enum":["OPEN","COMPLETE"]},"UsageAcceptance":{"type":"object","properties":{"tranche_id":{"type":"string","minLength":1,"maxLength":200},"commit":{"type":"string","pattern":"^[a-f0-9]{40}$"},"status":{"$ref":"#/components/schemas/UsageStatus"},"accepted_at":{"type":"string","description":"UTC ISO-8601 timestamp"}},"required":["tranche_id","commit","status","accepted_at"],"additionalProperties":false},"UsageAuthority":{"type":"object","properties":{"keyId":{"type":"string","maxLength":64},"root":{"type":"string","maxLength":100}},"required":["keyId","root"],"additionalProperties":false,"description":"A key Stood is configured to trust, outside the builder's tree"},"UsageReceipt":{"type":"object","properties":{"version":{"type":"number","const":1},"allowanceId":{"type":"string","minLength":1,"maxLength":200},"trancheId":{"type":"string","minLength":1,"maxLength":200},"commit":{"type":"string","pattern":"^[a-f0-9]{40}$","description":"The tranche's latest submitted package commit"},"authority":{"$ref":"#/components/schemas/UsageAuthority"},"observedAt":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"When the buyer confirmed use, Unix milliseconds (within 24 hours)"},"nonce":{"type":"string","pattern":"^[A-Za-z0-9_-]{16,200}$"},"signature":{"type":"string","maxLength":200,"description":"Base64 Ed25519 signature over \"stood-usage-receipt/v1\", allowanceId, trancheId, commit, keyId, root, observedAt and nonce, joined by NUL"}},"required":["version","allowanceId","trancheId","commit","authority","observedAt","nonce","signature"],"additionalProperties":false,"description":"The buyer's signed confirmation that a final milestone is in use"},"UsageStatus":{"type":"string","const":"ACCEPTED"}},"securitySchemes":{"platformKey":{"type":"http","scheme":"bearer","description":"The platform key"},"requestSignature":{"type":"apiKey","in":"header","name":"Stood-Signature","description":"t=<unix seconds>,v2=<hex HMAC-SHA256(secret, JSON [\"stood.request@2\", t, method, \"/v1\"+path+query, Idempotency-Key, If-Match, Content-Type, body])>"}}}}