{"openapi":"3.1.0","info":{"title":"The Enterprise Gallery API","version":"0.3.0","description":"Independent Gallery revision 0004. Public and authenticated browser APIs use the same-origin BFF. Provider ingress and origin health routes are private operations. See docs/API.md."},"servers":[{"url":"/","description":"Same-origin Enterprise Gallery public API and authenticated BFF"}],"paths":{"/api/csrf":{"get":{"summary":"GET /api/csrf","responses":{"200":{"description":"Success"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/me":{"get":{"summary":"GET /api/me","responses":{"200":{"description":"Success"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}},"security":[{"sessionCookie":[]}]}},"/api/public/businesses":{"get":{"summary":"GET /api/public/businesses","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","maxItems":30,"items":{"$ref":"#/components/schemas/PublicBusiness"}}}}},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}},"parameters":[{"in":"query","name":"q","schema":{"type":"string","maxLength":100}},{"in":"query","name":"country","schema":{"type":"string","pattern":"^[A-Z]{2}$"}},{"in":"query","name":"intent","schema":{"type":"string","enum":["browse","hire","quote","visit","partner","featured","all"]}},{"in":"query","name":"offset","schema":{"type":"integer","minimum":0,"maximum":10000}},{"in":"query","name":"region","schema":{"type":"string"}},{"in":"query","name":"city","schema":{"type":"string"}},{"in":"query","name":"category","schema":{"type":"string"}},{"in":"query","name":"collection","schema":{"type":"string"}},{"in":"query","name":"state","schema":{"type":"string","enum":["approved","agent-discoverable"]}}]}},"/api/public/businesses/{slug}":{"get":{"summary":"GET /api/public/businesses/{slug}","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicBusiness"}}}},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}},"parameters":[{"in":"path","name":"slug","required":true,"schema":{"type":"string"}}]}},"/api/plans":{"get":{"summary":"GET /api/plans","responses":{"200":{"description":"Success"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/workspace":{"get":{"summary":"GET /api/workspace","responses":{"200":{"description":"Success"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}},"security":[{"sessionCookie":[]}]}},"/api/saves":{"get":{"summary":"GET /api/saves","responses":{"200":{"description":"Success"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}},"security":[{"sessionCookie":[]}]},"post":{"summary":"POST /api/saves","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"slug":{"type":"string","maxLength":100},"saved":{"type":"boolean"}},"required":["slug","saved"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/admin":{"get":{"summary":"GET /api/admin","responses":{"200":{"description":"Success"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}},"security":[{"sessionCookie":[]}]}},"/api/integrations/envelopes":{"post":{"summary":"POST /api/integrations/envelopes","responses":{"200":{"description":"Success"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}},"parameters":[{"in":"header","name":"X-Signature","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"sender":{"type":"string","enum":["chima-local","leads-local","billing-local"]},"keyId":{"type":"string","minLength":1,"maxLength":80},"environment":{"const":"local_test"},"audience":{"const":"enterprise-gallery"},"eventId":{"type":"string","minLength":1,"maxLength":128},"nonce":{"type":"string","minLength":16,"maxLength":128},"timestamp":{"type":"integer"},"type":{"type":"string","enum":["projection.changed","lead.candidate","billing.checkout.completed"]},"schemaVersion":{"const":1},"payload":{"type":"object","description":"Strict event-specific schema; see PROVIDERS.md"}},"required":["sender","keyId","environment","audience","eventId","nonce","timestamp","type","schemaVersion","payload"]}}}}}},"/api/openapi.json":{"get":{"summary":"GET /api/openapi.json","responses":{"200":{"description":"Success"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/auth/signup":{"post":{"summary":"POST /api/auth/signup","security":[{"csrfToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","format":"email","maxLength":254},"password":{"type":"string","minLength":12,"maxLength":128},"name":{"type":"string","minLength":2,"maxLength":100},"legal":{"$ref":"#/components/schemas/LegalAcceptance"}},"required":["email","password","name","legal"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/auth/login":{"post":{"summary":"POST /api/auth/login","security":[{"csrfToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","format":"email","maxLength":254},"password":{"type":"string","minLength":12,"maxLength":128}},"required":["email","password"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/auth/logout":{"post":{"summary":"POST /api/auth/logout","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/auth/request-reset":{"post":{"summary":"POST /api/auth/request-reset","security":[{"csrfToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","format":"email","maxLength":254}},"required":["email"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/auth/confirm":{"post":{"summary":"POST /api/auth/confirm","security":[{"csrfToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"token":{"type":"string","minLength":32,"maxLength":100},"kind":{"type":"string","enum":["verify","reset"]},"password":{"type":"string","minLength":12,"maxLength":128}},"required":["token","kind"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/account":{"post":{"summary":"POST /api/account","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":2,"maxLength":100}},"required":["name"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/businesses":{"post":{"summary":"Retired direct owner-registration route; use the bounded /api/registration/begin and /api/registration/activate flow","deprecated":true,"security":[{"csrfToken":[],"sessionCookie":[]}],"responses":{"410":{"description":"Direct registration retired"}}}},"/api/businesses/{id}/edit":{"post":{"summary":"POST /api/businesses/{id}/edit","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Profile"}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/businesses/{id}/submit":{"post":{"summary":"POST /api/businesses/{id}/submit","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/businesses/{id}/hide":{"post":{"summary":"POST /api/businesses/{id}/hide","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/admin/candidates":{"post":{"summary":"POST /api/admin/candidates","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"provider":{"type":"string","minLength":1,"maxLength":80},"externalId":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","format":"email","maxLength":254},"sourceUrl":{"type":"string","format":"uri","maxLength":2048},"provenance":{"type":"object","additionalProperties":{"type":"string","maxLength":500},"minProperties":1},"confidence":{"type":"object","additionalProperties":{"type":"number","minimum":0,"maximum":1},"minProperties":1},"profile":{"$ref":"#/components/schemas/Profile"},"submitterType":{"type":"string","enum":["administrator","agent","provider"],"default":"administrator"}},"required":["provider","externalId","email","sourceUrl","provenance","confidence","profile"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}},"description":"Owner endpoint accepts only path=owner from a non-admin verified account. Assisted submissions use strict candidate import without legal/authority fields; no memberships or owner acceptances are created."}},"/api/admin/invitations":{"post":{"summary":"POST /api/admin/invitations","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"businessId":{"type":"string","format":"uuid"},"mode":{"type":"string","enum":["manual","scheduled","policy_automation","agent_assisted"]},"legalBasis":{"type":"string","maxLength":80},"consentReference":{"type":"string","maxLength":300},"scheduledAt":{"type":"string","format":"date-time"}},"required":["businessId","mode","legalBasis"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/activation/review":{"post":{"summary":"Compatibility alias for the one-time /api/activation/exchange operation","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"token":{"type":"string","minLength":32,"maxLength":100}},"required":["token"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/activation/confirm":{"post":{"summary":"Confirm a claim using the HttpOnly bounded activation session; raw email bearer tokens are never authorization","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"profile":{"$ref":"#/components/schemas/Profile"},"confirm":{"const":true},"legal":{"$ref":"#/components/schemas/LegalAcceptance"},"authorityStatement":{"type":"string","minLength":20,"maxLength":1000}},"required":["profile","confirm","legal","authorityStatement"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/businesses/{id}/billing":{"post":{"summary":"POST /api/businesses/{id}/billing","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"plan":{"type":"string","enum":["free","discoverable","plus"]},"interval":{"type":"string","enum":["month","year"]},"action":{"type":"string","enum":["checkout","cancel"]}},"required":["plan","interval","action"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/businesses/{id}/portal":{"post":{"summary":"POST /api/businesses/{id}/portal","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"},{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/admin/review":{"post":{"summary":"POST /api/admin/review","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"businessId":{"type":"string","format":"uuid"},"version":{"type":"integer","minimum":1},"decision":{"type":"string","enum":["approved","rejected"]},"note":{"type":"string","minLength":1,"maxLength":1000},"agentDiscoverable":{"type":"boolean","default":false,"description":"Reviewed opt-in for agent-specific discovery surfaces"}},"required":["businessId","version","decision","note"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/admin/suppress":{"post":{"summary":"POST /api/admin/suppress","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","format":"email","maxLength":254},"reason":{"type":"string","minLength":3,"maxLength":300}},"required":["email","reason"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/admin/outbox/retry":{"post":{"summary":"POST /api/admin/outbox/retry","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"}},"required":["id"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/test/billing/complete":{"post":{"summary":"/api/test/billing/complete","security":[{"sessionCookie":[],"csrfToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"checkoutId":{"type":"string","format":"uuid"}},"required":["checkoutId"]}}}},"responses":{"200":{"description":"Recorded"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Denied by role or review gate"},"409":{"description":"Conflict"},"503":{"description":"Provider unavailable"}}}},"/api/businesses/{id}/memberships":{"post":{"summary":"/api/businesses/{id}/memberships","security":[{"sessionCookie":[],"csrfToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["editor","remove"]}},"required":["email","role"]}}}},"responses":{"200":{"description":"Recorded"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Denied by role or review gate"},"409":{"description":"Conflict"},"503":{"description":"Provider unavailable"}}}},"/api/admin/authority":{"post":{"summary":"/api/admin/authority","security":[{"sessionCookie":[],"csrfToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"claimId":{"type":"string","format":"uuid"},"decision":{"type":"string","enum":["verified","rejected"]},"note":{"type":"string","minLength":20,"maxLength":1000}},"required":["claimId","decision","note"]}}}},"responses":{"200":{"description":"Recorded"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Denied by role or review gate"},"409":{"description":"Conflict"},"503":{"description":"Provider unavailable"}}}},"/api/account/delete":{"post":{"summary":"/api/account/delete","security":[{"sessionCookie":[],"csrfToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}},"responses":{"200":{"description":"Recorded"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Denied by role or review gate"},"409":{"description":"Conflict"},"503":{"description":"Provider unavailable"}}}},"/api/businesses/{id}/delete":{"post":{"summary":"/api/businesses/{id}/delete","security":[{"sessionCookie":[],"csrfToken":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}},"responses":{"200":{"description":"Recorded"},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Denied by role or review gate"},"409":{"description":"Conflict"},"503":{"description":"Provider unavailable"}}}},"/api/catalog":{"get":{"summary":"/api/catalog","responses":{"200":{"description":"Public data"},"404":{"description":"Not approved or not found"},"503":{"description":"Service unavailable"}}}},"/api/legal":{"get":{"summary":"/api/legal","responses":{"200":{"description":"Public data"},"404":{"description":"Not approved or not found"},"503":{"description":"Service unavailable"}}}},"/api/public/agent-card/{slug}":{"get":{"summary":"/api/public/agent-card/{slug}","responses":{"200":{"description":"Public data"},"404":{"description":"Not approved or not found"},"503":{"description":"Service unavailable"}},"parameters":[{"in":"path","name":"slug","required":true,"schema":{"type":"string","maxLength":100}},{"in":"query","name":"country","required":false,"description":"Optional ISO 3166-1 alpha-2 country scope for duplicate and claim search.","schema":{"type":"string","pattern":"^[A-Z]{2}$"}}]}},"/api/registration/search":{"get":{"summary":"Search approved public and explicitly reviewed minimal claim catalog names","responses":{"200":{"description":"Success; private/session endpoints require owner authorization"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}},"parameters":[{"in":"query","name":"q","required":true,"schema":{"type":"string","minLength":2,"maxLength":100}}]}},"/api/registration/begin":{"post":{"summary":"Verified owner only: accept versions and establish 15-minute HttpOnly activation session; admin/proxy acceptance forbidden","responses":{"200":{"description":"Success; private/session endpoints require owner authorization"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"profile":{"$ref":"#/components/schemas/Profile"},"legal":{"$ref":"#/components/schemas/LegalAcceptance"},"authorityAttested":{"type":"boolean","enum":[true]},"authorityStatement":{"type":"string","minLength":20,"maxLength":1000},"businessId":{"type":"string","format":"uuid"}},"required":["profile","legal","authorityAttested","authorityStatement"]}}}}}},"/api/registration/session":{"get":{"summary":"Resume a bounded registration with profile and active recommendations, including safe editable details, name, state, and reward slot","security":[{"sessionCookie":[],"activationCookie":[]}],"responses":{"200":{"description":"Current bounded session and allowlisted editable active recommendation details","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["profile","claim","expiresAt","recommendations"],"properties":{"profile":{"type":"object"},"claim":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"},"recommendations":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["id","name","state","rewardSlot","details"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"state":{"type":"string","enum":["pending","approved"]},"rewardSlot":{"type":"integer","minimum":1,"maximum":3},"details":{"type":"object","additionalProperties":false,"properties":{"email":{"type":"string","format":"email"},"phone":{"type":"string"},"website":{"type":"string","format":"uri","pattern":"^https://"},"city":{"type":"string"},"region":{"type":"string"},"country":{"type":"string","pattern":"^[A-Z]{2}$"},"categoryId":{"type":"string","format":"uuid"},"collectionId":{"type":"string","format":"uuid"},"highlights":{"type":"string"}}}}}}}}}}},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}}}},"/api/registration/activate":{"post":{"summary":"Owner deliberate activation: fresh exact legal versions, authorityAttested true, statement, profile, confirm true; consume session and return pending review","responses":{"200":{"description":"Success; private/session endpoints require owner authorization"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"profile":{"$ref":"#/components/schemas/Profile"},"legal":{"$ref":"#/components/schemas/LegalAcceptance"},"authorityAttested":{"type":"boolean","enum":[true]},"authorityStatement":{"type":"string","minLength":20,"maxLength":1000},"confirm":{"type":"boolean","enum":[true]}},"required":["profile","legal","authorityAttested","authorityStatement","confirm"]}}}}}},"/api/registration/recommendations":{"post":{"summary":"Create one of at most three active recommendations in the account onboarding cohort; 100 credits remain pending until review","responses":{"200":{"description":"Success; private/session endpoints require owner authorization"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":2,"maxLength":120},"appropriateBasis":{"type":"boolean","enum":[true]},"email":{"type":"string","format":"email"},"phone":{"type":"string","maxLength":40},"website":{"type":"string","format":"uri","pattern":"^https://"},"city":{"type":"string","maxLength":100},"region":{"type":"string","maxLength":100},"country":{"type":"string","pattern":"^[A-Z]{2}$","description":"Optional canonical ISO 3166-1 alpha-2 code from /api/countries"},"categoryId":{"type":"string","format":"uuid"},"collectionId":{"type":"string","format":"uuid"},"highlights":{"type":"string","maxLength":1000}},"required":["name","appropriateBasis"]}}}}}},"/api/registration/contact-review":{"post":{"summary":"Verified personal owner request for existing public profile; pending evidence review grants no ownership transfer","responses":{"200":{"description":"Success; private/session endpoints require owner authorization"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"legal":{"$ref":"#/components/schemas/LegalAcceptance"},"authorityAttested":{"type":"boolean","enum":[true]},"authorityStatement":{"type":"string","minLength":20,"maxLength":1000},"businessId":{"type":"string","format":"uuid"}},"required":["legal","authorityAttested","authorityStatement","businessId"]}}}}}},"/api/credits":{"get":{"summary":"Own local pending credit projection; spendable always zero","responses":{"200":{"description":"Success; private/session endpoints require owner authorization"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}}}},"/api/my-claims":{"get":{"summary":"Own authority claim status","responses":{"200":{"description":"Success; private/session endpoints require owner authorization"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}}}},"/api/admin/candidate-catalog":{"post":{"summary":"Admin review of name/country disclosure only; never publication or owner acceptance","responses":{"200":{"description":"Success; private/session endpoints require owner authorization"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"businessId":{"type":"string","format":"uuid"},"approved":{"type":"boolean"},"note":{"type":"string","minLength":20,"maxLength":1000}},"required":["businessId","approved","note"]}}}}}},"/api/capabilities":{"get":{"summary":"Environment-gated billing availability and reviewed public discovery capabilities","responses":{"200":{"description":"Success; private/session endpoints require owner authorization"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}}}},"/api/businesses/{id}/readiness":{"get":{"summary":"Member-scoped deterministic profile/card/current approval checks; never external placement guarantee","responses":{"200":{"description":"Success; private/session endpoints require owner authorization"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, purpose or session denied"},"409":{"description":"Duplicate, self-referral, capacity or state conflict"},"503":{"description":"Provider or service unavailable"}}}},"/api/activation/exchange":{"post":{"summary":"Exchange a one-time email bearer for a purpose-bound, auth-session-bound, HttpOnly 15-minute claim-activation session","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"token":{"type":"string","minLength":32,"maxLength":100}},"required":["token"]}}}},"responses":{"200":{"description":"One-time bearer consumed and bounded activation session established"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/activation/session":{"get":{"summary":"Read the active claim review through the bounded activation-session cookie","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Bounded activation review"},"401":{"description":"Sign in required"},"403":{"description":"Activation session expired, consumed, or bound to another authentication session"}}}},"/api/recommendations/{id}/correct":{"post":{"summary":"Owner-correct a pending recommendation without deleting its immutable history or pending-credit record","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":2,"maxLength":120},"appropriateBasis":{"type":"boolean","enum":[true]},"email":{"type":"string","format":"email"},"phone":{"type":"string","maxLength":40},"website":{"type":"string","format":"uri","pattern":"^https://"},"city":{"type":"string","maxLength":100},"region":{"type":"string","maxLength":100},"country":{"type":"string","pattern":"^[A-Z]{2}$","description":"Optional canonical ISO 3166-1 alpha-2 code from /api/countries"},"categoryId":{"type":"string","format":"uuid"},"collectionId":{"type":"string","format":"uuid"},"highlights":{"type":"string","maxLength":1000}},"required":["name","appropriateBasis"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, CSRF, or session denied"},"404":{"description":"Not found"},"409":{"description":"State or duplicate conflict"}}}},"/api/recommendations/{id}/remove":{"post":{"summary":"Owner-cancel a pending recommendation and void its pending credit/outbox while retaining audit history","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"reason":{"type":"string","minLength":5,"maxLength":500}},"required":["reason"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, CSRF, or session denied"},"404":{"description":"Not found"},"409":{"description":"State or duplicate conflict"}}}},"/api/admin/recommendations/{id}/review":{"post":{"summary":"Administrator approve or reject a pending recommendation; approval activates its credit and rejection safely frees its cohort slot","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"decision":{"type":"string","enum":["approved","rejected"]},"note":{"type":"string","minLength":20,"maxLength":1000}},"required":["decision","note"]}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Validation failure"},"401":{"description":"Authentication required"},"403":{"description":"Role, ownership, CSRF, or session denied"},"404":{"description":"Not found"},"409":{"description":"State or duplicate conflict"}}}},"/api/registration/cancel":{"post":{"summary":"Cancel the active bounded registration, its pending recommendations, credits, and queued pending recommendation work without deleting audit history","security":[{"csrfToken":[],"sessionCookie":[],"activationCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"confirm":{"const":true}},"required":["confirm"]}}}},"responses":{"200":{"description":"Cancelled, or identical idempotent replay of the completed cancellation","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["state","cancelledRecommendations","creditsVoided"],"properties":{"state":{"const":"cancelled"},"cancelledRecommendations":{"type":"integer","minimum":0},"creditsVoided":{"type":"integer","minimum":0}}}}}},"400":{"description":"Invalid strict confirmation body"},"401":{"description":"Authentication required"},"403":{"description":"Registration session expired, consumed, or bound to another authentication session"},"409":{"description":"Idempotency key reused with different input"}}}},"/api/v1/businesses/{id}/verification":{"get":{"summary":"Verified human owner-scoped verification state and bounded feedback","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Current versioned verification state; no public private proof"},"400":{"description":"Strict input validation failure"},"401":{"description":"Authenticated signed edge/session required"},"403":{"description":"Business owner, eligibility or independent administrator denied"},"409":{"description":"Version, idempotency, proof, profile or state conflict"},"429":{"description":"Bounded proof checks or request limit"},"503":{"description":"Unavailable capability"}}}},"/api/admin/businesses/{id}/verification":{"get":{"summary":"Independent administrator private verification review","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Current versioned verification state; no public private proof"},"400":{"description":"Strict input validation failure"},"401":{"description":"Authenticated signed edge/session required"},"403":{"description":"Business owner, eligibility or independent administrator denied"},"409":{"description":"Version, idempotency, proof, profile or state conflict"},"429":{"description":"Bounded proof checks or request limit"},"503":{"description":"Unavailable capability"}}}},"/api/v1/businesses/{id}/verification/request":{"post":{"summary":"Request current eligible business verification","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"csrfToken":[],"idempotencyKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["confirm"],"properties":{"confirm":{"const":true}}}}}},"responses":{"200":{"description":"Current versioned verification state; no public private proof"},"400":{"description":"Strict input validation failure"},"401":{"description":"Authenticated signed edge/session required"},"403":{"description":"Business owner, eligibility or independent administrator denied"},"409":{"description":"Version, idempotency, proof, profile or state conflict"},"429":{"description":"Bounded proof checks or request limit"},"503":{"description":"Unavailable capability"}}}},"/api/v1/businesses/{id}/verification/challenge":{"post":{"summary":"Create one-time bounded DNS TXT control challenge","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"csrfToken":[],"idempotencyKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["requestId","expectedVersion"],"properties":{"requestId":{"type":"string","format":"uuid"},"expectedVersion":{"type":"integer","minimum":1}}}}}},"responses":{"200":{"description":"Current versioned verification state; no public private proof"},"400":{"description":"Strict input validation failure"},"401":{"description":"Authenticated signed edge/session required"},"403":{"description":"Business owner, eligibility or independent administrator denied"},"409":{"description":"Version, idempotency, proof, profile or state conflict"},"429":{"description":"Bounded proof checks or request limit"},"503":{"description":"Unavailable capability"}}}},"/api/v1/businesses/{id}/verification/check":{"post":{"summary":"Check domain control; never issue badge from proof alone","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"csrfToken":[],"idempotencyKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["requestId","expectedVersion"],"properties":{"requestId":{"type":"string","format":"uuid"},"expectedVersion":{"type":"integer","minimum":1}}}}}},"responses":{"200":{"description":"Current versioned verification state; no public private proof"},"400":{"description":"Strict input validation failure"},"401":{"description":"Authenticated signed edge/session required"},"403":{"description":"Business owner, eligibility or independent administrator denied"},"409":{"description":"Version, idempotency, proof, profile or state conflict"},"429":{"description":"Bounded proof checks or request limit"},"503":{"description":"Unavailable capability"}}}},"/api/admin/businesses/{id}/verification/decision":{"post":{"summary":"Independent evidence-backed versioned decision; payment cannot issue verification","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"csrfToken":[],"idempotencyKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["requestId","expectedVersion","policyVersion","decision","note"],"properties":{"requestId":{"type":"string","format":"uuid"},"expectedVersion":{"type":"integer","minimum":1},"policyVersion":{"const":"gallery-verification-v1-2026-10-01"},"decision":{"enum":["needs_information","verified","declined","suspended","expired"]},"note":{"type":"string","minLength":20,"maxLength":2000},"evidence":{"type":"object","additionalProperties":false,"required":["sourceDescription","checkedFacts","factsConsistent","ownershipConflict","disqualifyingRisk"],"properties":{"sourceDescription":{"type":"string","minLength":20,"maxLength":2000},"sourceUrl":{"type":"string","format":"uri","description":"Public HTTPS source only"},"checkedFacts":{"type":"array","minItems":1,"maxItems":5,"items":{"enum":["name","country","website","location","services"]}},"factsConsistent":{"type":"boolean"},"ownershipConflict":{"type":"boolean"},"disqualifyingRisk":{"type":"boolean"}}}},"description":"Passing requires consistent reviewed evidence, current profile, fresh control proof and no unresolved conflict/risk."}}}},"responses":{"200":{"description":"Current versioned verification state; no public private proof"},"400":{"description":"Strict input validation failure"},"401":{"description":"Authenticated signed edge/session required"},"403":{"description":"Business owner, eligibility or independent administrator denied"},"409":{"description":"Version, idempotency, proof, profile or state conflict"},"429":{"description":"Bounded proof checks or request limit"},"503":{"description":"Unavailable capability"}}}},"/api/businesses/{id}/discovery-refresh":{"post":{"summary":"Queue a priority Gallery discovery-index refresh for an authorized current paid business owner","description":"Internal approved public facts only. One-minute per-business cooldown. Does not publish drafts, grant verification or control external indexing.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"name":"X-CSRF-Token","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false}}}},"responses":{"200":{"description":"Priority refresh queued, with current internal index status"},"401":{"description":"Sign in required"},"403":{"description":"Current verified human owner and paid membership required"},"409":{"description":"Approved public profile or current request required"},"429":{"description":"Refresh cooldown active"}},"security":[{"sessionCookie":[],"csrfToken":[]}]}},"/api/public/homepage-businesses":{"get":{"summary":"Read ordered eligible homepage selections","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","maxItems":12,"items":{"$ref":"#/components/schemas/HomepageBusiness"}}}}},"400":{"description":"Invalid input"},"401":{"description":"Authentication required"},"403":{"description":"Not permitted"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}}}},"/api/admin/homepage-selection":{"get":{"summary":"Admin: list up to500 business editorial controls, selected records first","security":[{"sessionCookie":[]}],"responses":{"200":{"description":"Business ID, name, slug, publication state, company_label, homepage_position and eligibility only"},"401":{"description":"Authentication required"},"403":{"description":"Admin required"}}},"post":{"summary":"Admin: update company labels and explicit homepage positions","security":[{"csrfToken":[],"sessionCookie":[]}],"parameters":[{"in":"header","name":"Idempotency-Key","required":true,"schema":{"type":"string","minLength":16,"maxLength":128}},{"in":"header","name":"Origin","required":true,"schema":{"type":"string"},"example":"https://gallery.example.invalid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["entries"],"properties":{"entries":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","additionalProperties":false,"required":["businessId","companyLabel","homepagePosition","expectedCompanyLabel","expectedHomepagePosition"],"properties":{"businessId":{"type":"string","format":"uuid"},"companyLabel":{"enum":["company_business","internal",null]},"homepagePosition":{"type":["integer","null"],"minimum":1,"maximum":12},"expectedCompanyLabel":{"enum":["company_business","internal",null]},"expectedHomepagePosition":{"type":["integer","null"],"minimum":1,"maximum":12}}}}}}}}},"responses":{"200":{"description":"Committed or identical idempotent replay"},"400":{"description":"Invalid input"},"401":{"description":"Sign in required"},"403":{"description":"Origin, CSRF, ownership or admin denied"},"404":{"description":"Not found"},"409":{"description":"Conflict"},"429":{"description":"Rate limit exceeded"},"500":{"description":"Internal error with request ID"}},"description":"Partial batch, max100 records. Published eligibility is required only for non-null homepage positions. Company labels do not confer verification or ownership. No email or billing actions. Expected prior label and position are required; stale forms return409 without any editorial writes. Reload before resubmitting."}}},"components":{"securitySchemes":{"sessionCookie":{"type":"apiKey","in":"cookie","name":"gallery_session"},"activationCookie":{"type":"apiKey","in":"cookie","name":"gallery_activation"},"csrfToken":{"type":"apiKey","in":"header","name":"X-CSRF-Token"}},"schemas":{"PublicBusiness":{"type":"object","additionalProperties":false,"required":["slug","name","description","country","website","intent"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"country":{"type":"string"},"intent":{"type":"string"},"website":{"type":["string","null"],"format":"uri"},"categories":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]}},"collections":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]}},"location":{"oneOf":[{"type":"null"},{"type":"object","additionalProperties":false,"properties":{"city":{"type":"string"},"region":{"type":"string"},"countryCode":{"type":"string"},"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"postalCode":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"}},"required":["city","region","countryCode"]}]},"gallery_verification_status":{"type":"string","enum":["verified","not_verified"]},"gallery_verified_at":{"type":["string","null"],"format":"date-time"},"gallery_verification_valid_through":{"type":["string","null"],"format":"date-time"},"gallery_verification_label":{"type":["string","null"]},"gallery_verification_url":{"type":["string","null"]},"enhanced_discovery":{"type":"object","description":"Current paid membership enhancement from the matching approved public profile; absent for Free or ineligible profiles.","additionalProperties":true}}},"Profile":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":2,"maxLength":120},"slug":{"type":"string","minLength":3,"maxLength":100,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"description":{"type":"string","minLength":10,"maxLength":4000},"tagline":{"type":"string","maxLength":80,"description":"Optional whitespace-normalized tagline. Omission preserves an existing value on edit."},"showcase":{"$ref":"#/components/schemas/BusinessShowcase"},"country":{"type":"string","pattern":"^[A-Z]{2}$"},"website":{"type":"string","format":"uri","pattern":"^https://","maxLength":2048},"intent":{"type":"string","enum":["browse","hire","quote","visit","partner","featured"]},"categoryIds":{"type":"array","maxItems":8,"items":{"type":"string","format":"uuid"}},"collectionIds":{"type":"array","maxItems":8,"items":{"type":"string","format":"uuid"}},"location":{"$ref":"#/components/schemas/Location"}},"required":["name","slug","description","country","intent"]},"BusinessShowcase":{"type":"object","additionalProperties":false,"required":["type","content"],"description":"Validated structured rich text, not HTML. Canonical validator: packages/core/src/showcase.ts. Maximum 64KB UTF-8, 500 nodes, depth 8, 12 external images, 4 YouTube/Vimeo videos. Public HTTPS URLs only; no uploads, scripts, custom CSS or arbitrary iframes. Omission preserves existing content on edit; an empty doc clears it.","properties":{"type":{"const":"doc"},"content":{"type":"array","maxItems":100,"items":{"type":"object","description":"Strictly validated paragraph, heading (2/3), text, hardBreak, horizontalRule, bulletList, orderedList, listItem, blockquote or externalMedia. Canonical validator defines nesting, attributes and text marks."}}}},"LegalAcceptance":{"type":"object","additionalProperties":false,"properties":{"termsVersion":{"const":"gallery-terms-2026-09-08"},"privacyVersion":{"const":"gallery-privacy-2026-09-08"},"accepted":{"const":true}},"required":["termsVersion","privacyVersion","accepted"]},"Location":{"type":"object","additionalProperties":false,"properties":{"addressLine1":{"type":"string","maxLength":150},"addressLine2":{"type":"string","maxLength":150},"city":{"type":"string","maxLength":100},"region":{"type":"string","maxLength":100},"postalCode":{"type":"string","maxLength":30},"countryCode":{"type":"string","pattern":"^[A-Z]{2}$"},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"providerReference":{"type":"string","maxLength":200},"visibility":{"type":"string","enum":["private","locality","full"]}},"required":["addressLine1","city","region","postalCode","countryCode"]},"HomepageBusiness":{"type":"object","additionalProperties":false,"required":["slug","name","description","country","website","intent"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"country":{"type":"string"},"intent":{"type":"string"},"website":{"type":["string","null"],"format":"uri"},"categories":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]}},"collections":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]}},"location":{"oneOf":[{"type":"null"},{"type":"object","additionalProperties":false,"properties":{"city":{"type":"string"},"region":{"type":"string"},"countryCode":{"type":"string"},"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"postalCode":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"}},"required":["city","region","countryCode"]}]},"gallery_verification_status":{"type":"string","enum":["verified","not_verified"]},"gallery_verified_at":{"type":["string","null"],"format":"date-time"},"gallery_verification_valid_through":{"type":["string","null"],"format":"date-time"},"gallery_verification_label":{"type":["string","null"]},"gallery_verification_url":{"type":["string","null"]},"enhanced_discovery":{"type":"object","description":"Current paid membership enhancement from the matching approved public profile; absent for Free or ineligible profiles.","additionalProperties":true},"homepage_disclosure":{"type":"string","enum":["Company business","Gallery selection"]},"agent_discoverable":{"type":"boolean"}}}}}}