{"openapi":"3.1.0","info":{"title":"sn33 paid API","version":"0.1.0"},"paths":{"/jobs-api/v1/quote":{"post":{"tags":["quote"],"summary":"Post Quote","operationId":"post_quote_jobs_api_v1_quote_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"},"examples":{"website":{"summary":"category=WEBSITE (raw text)","value":{"jobType":"tagging","declaredSize":256,"category":"WEBSITE"}},"ner":{"summary":"category=NAMED_ENTITY_RECOGNITION (raw text)","value":{"jobType":"tagging","declaredSize":256,"category":"NAMED_ENTITY_RECOGNITION"}},"city_council_notes":{"summary":"category=CITY_COUNCIL_NOTES (raw text)","value":{"jobType":"tagging","declaredSize":256,"category":"CITY_COUNCIL_NOTES"}}}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs-api/v1/jobs":{"post":{"tags":["jobs"],"summary":"Post Job","operationId":"post_job_jobs_api_v1_jobs_post","parameters":[{"name":"X-PAYMENT","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Payment"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobRequest"},"examples":{"website":{"summary":"category=WEBSITE (raw text)","value":{"quoteId":"q_...","jobType":"tagging","category":"WEBSITE","payload":{"content":"<page text>"}}},"ner":{"summary":"category=NAMED_ENTITY_RECOGNITION (raw text)","value":{"quoteId":"q_...","jobType":"tagging","category":"NAMED_ENTITY_RECOGNITION","payload":{"content":"<text to extract entities from>"}}},"city_council_notes":{"summary":"category=CITY_COUNCIL_NOTES (raw text)","value":{"quoteId":"q_...","jobType":"tagging","category":"CITY_COUNCIL_NOTES","payload":{"content":"<meeting minutes text>"}}}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobResponse"}}}},"402":{"description":"Payment required"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs-api/v1/jobs/{job_id}":{"get":{"tags":["jobs"],"summary":"Get Job","operationId":"get_job_jobs_api_v1_jobs__job_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"Category":{"type":"string","enum":["CONVERSATION","WEBSITE","NAMED_ENTITY_RECOGNITION","CITY_COUNCIL_NOTES"],"title":"Category"},"ConversationPayload":{"properties":{"turns":{"items":{"prefixItems":[{"type":"string","maxLength":200,"minLength":1},{"type":"string","minLength":1}],"type":"array","maxItems":2,"minItems":2},"type":"array","maxItems":10000,"minItems":1,"title":"Turns","description":"Ordered list of `[speaker, line]` pairs. Order is preserved end-to-end through the worker. As a convenience for speakerless transcripts, you may instead send a flat list of line strings (e.g. `[\"line 1\", \"line 2\"]`); each entry is normalized server-side to `[\"UNKNOWN_SPEAKER\", line]` before persistence. `UNKNOWN_SPEAKER` chars are excluded from `declaredSize` accounting — speakerless input is billed as if you had sent just the lines. Mixed input is rejected."}},"additionalProperties":false,"type":"object","required":["turns"],"title":"ConversationPayload","description":"Payload for CONVERSATION. Required shape when `category=CONVERSATION`."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"JobRequest":{"properties":{"quoteId":{"type":"string","title":"Quoteid"},"jobType":{"$ref":"#/components/schemas/JobType"},"category":{"$ref":"#/components/schemas/Category"},"payload":{"anyOf":[{"$ref":"#/components/schemas/ConversationPayload"},{"$ref":"#/components/schemas/TextPayload"}],"title":"Payload","description":"Shape depends on `category`. CONVERSATION → ConversationPayload `{turns: [{speaker, line}, ...]}`. WEBSITE / NAMED_ENTITY_RECOGNITION / CITY_COUNCIL_NOTES → TextPayload `{content: str}`. Sending the wrong shape for a category returns HTTP 422."}},"additionalProperties":false,"type":"object","required":["quoteId","jobType","category","payload"],"title":"JobRequest"},"JobResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"jobId":{"type":"string","title":"Jobid"},"status":{"$ref":"#/components/schemas/JobStatus"},"token":{"type":"string","title":"Token"}},"type":"object","required":["success","jobId","status","token"],"title":"JobResponse"},"JobStatus":{"type":"string","enum":["queued","processing","complete","failed"],"title":"JobStatus"},"JobStatusResponse":{"properties":{"status":{"$ref":"#/components/schemas/JobStatus"},"result":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Result"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"expiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expiresat"}},"type":"object","required":["status"],"title":"JobStatusResponse","description":"Polymorphic by `status`. Use `model_dump(exclude_none=True)` so queued/processing\nresponses don't carry empty `result`/`error`/`expiresAt` fields."},"JobType":{"type":"string","enum":["tagging"],"title":"JobType"},"QuoteRequest":{"properties":{"jobType":{"$ref":"#/components/schemas/JobType"},"declaredSize":{"type":"integer","exclusiveMinimum":0.0,"title":"Declaredsize"},"category":{"$ref":"#/components/schemas/Category"}},"additionalProperties":false,"type":"object","required":["jobType","declaredSize","category"],"title":"QuoteRequest"},"QuoteResponse":{"properties":{"quoteId":{"type":"string","title":"Quoteid"},"requiredAmount":{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$","title":"Requiredamount"},"currency":{"type":"string","title":"Currency"},"network":{"type":"string","title":"Network"},"expiresAt":{"type":"string","format":"date-time","title":"Expiresat"}},"type":"object","required":["quoteId","requiredAmount","currency","network","expiresAt"],"title":"QuoteResponse"},"TextPayload":{"properties":{"content":{"type":"string","minLength":1,"title":"Content","description":"Raw text to tag."}},"additionalProperties":false,"type":"object","required":["content"],"title":"TextPayload","description":"Payload for raw-text categories (WEBSITE, NAMED_ENTITY_RECOGNITION, CITY_COUNCIL_NOTES)."},"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","description":"Job JWT issued by POST /v1/jobs","scheme":"bearer"}}}}