{"openapi":"3.1.0","info":{"title":"Artifacta API","version":"0.1.0"},"paths":{"/health":{"get":{"summary":"Health Check","description":"Unauthenticated health probe. Checks Postgres connectivity.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/whoami":{"get":{"summary":"Whoami","description":"Return tenant identity, plan, and usage counters.\n\nReads one row from the tenants table using the tenant_id resolved by auth.\nDoes not expose tenant_id, full API key, or other internal fields.","operationId":"whoami_v1_whoami_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Whoami V1 Whoami Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/artifacts":{"get":{"summary":"List Artifacts Endpoint","description":"List artifacts with filters and cursor pagination.","operationId":"list_artifacts_endpoint_v1_artifacts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"summary":"Create Artifact","description":"Upload an artifact via multipart/form-data or application/json.","operationId":"create_artifact_v1_artifacts_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/artifacts/upload-url":{"post":{"summary":"Create Upload Url","description":"Get a presigned URL for uploading a large file directly to R2.","operationId":"create_upload_url_v1_artifacts_upload_url_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/artifacts/{artifact_id}/complete":{"post":{"summary":"Complete Upload","description":"Finalize an artifact after presigned upload. Transitions pending → active.","operationId":"complete_upload_v1_artifacts__artifact_id__complete_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"artifact_id","in":"path","required":true,"schema":{"type":"string","title":"Artifact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/artifacts/{artifact_id}/links":{"post":{"summary":"Create Download Link","description":"Create a temporary download link for an artifact.","operationId":"create_download_link_v1_artifacts__artifact_id__links_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"artifact_id","in":"path","required":true,"schema":{"type":"string","title":"Artifact Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/artifacts/{artifact_id}/download-url":{"get":{"summary":"Get Artifact Download Url","description":"Get a presigned download URL for an artifact.","operationId":"get_artifact_download_url_v1_artifacts__artifact_id__download_url_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"artifact_id","in":"path","required":true,"schema":{"type":"string","title":"Artifact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/artifacts/{artifact_id}":{"get":{"summary":"Get Artifact","description":"Get metadata for a single artifact, including its publish state.","operationId":"get_artifact_v1_artifacts__artifact_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"artifact_id","in":"path","required":true,"schema":{"type":"string","title":"Artifact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Artifact","description":"Soft-delete an artifact. Sets deleted_at, decrements storage counter.","operationId":"delete_artifact_v1_artifacts__artifact_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"artifact_id","in":"path","required":true,"schema":{"type":"string","title":"Artifact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/artifacts/{artifact_id}/publish":{"post":{"summary":"Publish Artifact","description":"Publish an artifact as a public page (upsert artifact_pages; mint slug on first publish).","operationId":"publish_artifact_v1_artifacts__artifact_id__publish_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"artifact_id","in":"path","required":true,"schema":{"type":"string","title":"Artifact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/artifacts/{id_or_slug}/publish":{"delete":{"summary":"Unpublish Artifact","description":"Soft-unpublish a page (sets unpublished_at). Accepts an art_ id or a pg_ slug,\nresolved within the caller's tenant — the public slug never authorizes cross-tenant mutation.","operationId":"unpublish_artifact_v1_artifacts__id_or_slug__publish_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"id_or_slug","in":"path","required":true,"schema":{"type":"string","title":"Id Or Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sessions":{"get":{"summary":"List Sessions","description":"List sessions with artifact counts, seal status, and pagination.","operationId":"list_sessions_v1_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/sessions/{session_id}/seal":{"post":{"summary":"Seal Session","description":"Seal a session to prevent new artifact uploads.","operationId":"seal_session_v1_sessions__session_id__seal_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/public/pages/{slug}/gate-info":{"get":{"summary":"Gate Info","description":"Minimal gate signal for a gated page. 404 for missing/free/dead/suspended (no oracle).","operationId":"gate_info_v1_public_pages__slug__gate_info_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/public/pages/{slug}/unlock":{"post":{"summary":"Unlock Page","description":"Verify a passcode (argon2id, service_role) and mint a short-lived content token.\nInert (404) until Plan 6 enables pages_gate_enabled AND ships the durable brute-force\nlimiter + per-slug attempt cap + gated byte path that consumes this token (§6.4).","operationId":"unlock_page_v1_public_pages__slug__unlock_post","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/public/pages/{slug}/report":{"post":{"summary":"Report Page","description":"No-oracle abuse intake. Returns 202 for ANY slug (never reveals existence),\nrate-limited, sinks to PostHog (+ optional Slack). No DB write — takedown is the\nexisting tenant-scoped unpublish + deletion_scheduled_at (operator action).","operationId":"report_page_v1_public_pages__slug__report_post","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}