{"openapi":"3.1.0","info":{"title":"GradeThread API","version":"1.0.0","description":"Programmatic AI condition grading for pre-owned clothing. Submit garment photos, receive a 1.0–10.0 grade + condition report + shareable certificate. All responses use the envelope `{ data, error, meta }`. On success `error` is null; on failure `data` is null and `error` is `{ message, details }` (some errors add `code`). Two exceptions predate the envelope: a 401 from auth returns `{ error: string }`, and a 429 from the monthly-quota gate returns `{ error, code: \"quota_exceeded\", resets_at }`.\n\nAuthenticate with the `X-API-Key` header (Business plan). A free, deterministic sandbox lives under `/api/v1/sandbox/*` (same auth + scopes, no credits, no writes). Rate limits are per-key, per-minute, split into read (GET) and write budgets; the monthly call quota is reported by `GET /api/v1/usage`. Human docs: https://gradethread.com/developers","contact":{"name":"GradeThread Developer Support","url":"https://gradethread.com/developers"}},"servers":[{"url":"https://functions.gradethread.com","description":"Production"}],"security":[{"ApiKeyAuth":[]}],"tags":[{"name":"Grading","description":"Submit garments and retrieve grade reports."},{"name":"Batch","description":"Grade many garments in one call (durable, async)."},{"name":"Price Guide","description":"Resale Condition Index value data by item + grade band."},{"name":"Account","description":"Usage, quota, and webhook configuration."},{"name":"Sandbox","description":"Free, deterministic mock endpoints for integration testing."}],"paths":{"/api/v1/grades":{"post":{"tags":["Grading"],"summary":"Submit a garment for grading","description":"Uploads photos and enqueues grading. Charges via included grades → credits; if neither covers it, returns 402. Images may be `url` (https) or base64. Requires `front`, `back`, `label`, and at least one `detail*` image; max 14 images.","security":[{"ApiKeyAuth":["submit"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GradeSubmissionRequest"}}}},"responses":{"202":{"description":"Accepted — grading in progress","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GradeAccepted"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"402":{"description":"Payment required — insufficient included grades / credits","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"503":{"description":"Grading temporarily unavailable","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}}}},"get":{"tags":["Grading"],"summary":"List grade submissions","security":[{"ApiKeyAuth":["read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"status","in":"query","schema":{"type":"string"},"description":"Optional status filter."}],"responses":{"200":{"description":"Paginated list","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/GradeListItem"}},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}}}}},"/api/v1/grades/{id}":{"get":{"tags":["Grading"],"summary":"Get a grade report","security":[{"ApiKeyAuth":["read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The submission and its grade report (null until completed)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GradeDetail"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}}}}},"/api/v1/grades/batch":{"post":{"tags":["Batch"],"summary":"Submit up to 50 garments as one batch","description":"Validates every garment (same rules as a single grade) and rejects the whole batch on any invalid one. Returns immediately; each garment is graded in the background and charged individually. Poll `GET /api/v1/grades/batch/{id}`. A `grade.completed` webhook also fires per garment. Prefer image URLs over base64 in a batch.","security":[{"ApiKeyAuth":["submit"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["garments"],"properties":{"garments":{"type":"array","minItems":1,"maxItems":50,"items":{"$ref":"#/components/schemas/GradeSubmissionRequest"}}}}}}},"responses":{"202":{"description":"Batch accepted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BatchAccepted"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"403":{"description":"Error envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"503":{"description":"Error envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}}}}},"/api/v1/grades/batch/{id}":{"get":{"tags":["Batch"],"summary":"Poll a batch's status + per-garment results","security":[{"ApiKeyAuth":["read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Batch status (partial-success semantics)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BatchStatus"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}}}}},"/api/v1/usage":{"get":{"tags":["Account"],"summary":"This key's monthly usage vs quota","security":[{"ApiKeyAuth":["read"]}],"responses":{"200":{"description":"Quota state","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/QuotaState"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}}}}},"/api/v1/webhook":{"patch":{"tags":["Account"],"summary":"Set or clear the grade-completion webhook URL","description":"Applies to ALL of your API keys. The URL must be https + publicly routable. GradeThread POSTs a `grade.completed` event when a grade finalizes, signed with `X-GradeThread-Signature` (HMAC-SHA256 of the body, using that key's hash as the secret). See the GradeCompletedEvent schema.","security":[{"ApiKeyAuth":["webhook_manage"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["webhook_url"],"properties":{"webhook_url":{"type":"string","format":"uri","nullable":true,"description":"null clears it."}}}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"webhook_url":{"type":"string","nullable":true},"keys_updated":{"type":"integer"}}},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"400":{"description":"Error envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}}}}},"/api/v1/price-guide":{"get":{"tags":["Price Guide"],"summary":"Resale Condition Index catalog","security":[{"ApiKeyAuth":["read"]}],"responses":{"200":{"description":"Catalog of priced items","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PriceGuideCatalogItem"}}}},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}}}}},"/api/v1/price-guide/{slug}":{"get":{"tags":["Price Guide"],"summary":"Value bands for one item","security":[{"ApiKeyAuth":["read"]}],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Item value bands by grade","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PriceGuideEntry"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}},"404":{"description":"Error envelope","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"null"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}}}}},"/api/v1/sandbox/grades":{"post":{"tags":["Sandbox"],"summary":"Deterministic mock grade (no credits, no writes)","description":"Same auth + `submit` scope as production. Returns a deterministic sample grade.","security":[{"ApiKeyAuth":["submit"]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Sample grade (meta.sandbox = true)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"error":{"$ref":"#/components/schemas/ApiError"},"meta":{"type":"object","nullable":true}},"required":["data","error","meta"]}}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Your secret key, format `gt_sk_` + 64 hex chars. Create + rotate keys in the dashboard (Business plan). Scopes: `read`, `submit`, `webhook_manage` — a route requires the scope listed on it (the OAuth-scope notation here maps to key scopes)."}},"schemas":{"ApiError":{"type":"object","nullable":true,"properties":{"message":{"type":"string"},"code":{"type":"string"},"details":{"type":"array","items":{}}}},"GradeImage":{"type":"object","required":["image_type"],"description":"Provide exactly one of `url` (https) or `base64` (+ `content_type`).","properties":{"image_type":{"type":"string","enum":["front","back","label","label_2","detail","detail_2","detail_3","detail_4","defect","measurement_chest","measurement_waist","measurement_length","measurement_sleeve","measurement_inseam"]},"url":{"type":"string","format":"uri"},"base64":{"type":"string"},"content_type":{"type":"string","enum":["image/jpeg","image/png","image/webp"]}}},"GradeSubmissionRequest":{"type":"object","required":["title","garment_type","garment_category","images"],"properties":{"title":{"type":"string"},"garment_type":{"type":"string","enum":["tops","bottoms","outerwear","dresses","footwear","accessories"]},"garment_category":{"type":"string","enum":["t-shirt","shirt","blouse","sweater","hoodie","jacket","coat","jeans","pants","shorts","skirt","dress","sneakers","boots","sandals","hat","bag","belt","scarf","other"]},"brand":{"type":"string"},"description":{"type":"string"},"tier":{"type":"string","enum":["standard","premium","express"],"default":"standard"},"images":{"type":"array","minItems":1,"maxItems":14,"description":"Must include front, back, label + ≥1 detail*; each image_type at most once.","items":{"$ref":"#/components/schemas/GradeImage"}}}},"GradeAccepted":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","example":"processing"},"tier":{"type":"string","enum":["standard","premium","express"]},"payment_method":{"type":"string","enum":["included","credits"]}}},"GradeReport":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"overall_score":{"type":"number","minimum":1,"maximum":10},"grade_tier":{"type":"string"},"fabric_condition_score":{"type":"number"},"structural_integrity_score":{"type":"number"},"cosmetic_appearance_score":{"type":"number"},"functional_elements_score":{"type":"number"},"odor_cleanliness_score":{"type":"number"},"confidence_score":{"type":"number","minimum":0,"maximum":1},"ai_summary":{"type":"string"},"detailed_notes":{"type":"string"},"model_version":{"type":"string"},"certificate_id":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"GradeDetail":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","processing","completed","disputed","failed"]},"garment_type":{"type":"string"},"garment_category":{"type":"string"},"title":{"type":"string"},"brand":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"grade_report":{"oneOf":[{"$ref":"#/components/schemas/GradeReport"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"GradeListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"garment_type":{"type":"string"},"garment_category":{"type":"string"},"title":{"type":"string"},"brand":{"type":"string","nullable":true},"grade":{"type":"object","nullable":true,"properties":{"overall_score":{"type":"number"},"grade_tier":{"type":"string"},"confidence_score":{"type":"number"},"certificate_id":{"type":"string","nullable":true}}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"BatchAccepted":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","example":"running"},"item_count":{"type":"integer"}}},"BatchStatus":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","running","completed","failed","partial"]},"item_count":{"type":"integer"},"succeeded_count":{"type":"integer"},"failed_count":{"type":"integer"},"error":{"type":"string","nullable":true},"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","running","completed","failed"]},"grade_id":{"type":"string","format":"uuid","nullable":true},"error":{"type":"string","nullable":true}}}}}},"QuotaState":{"type":"object","properties":{"quota":{"type":"integer","nullable":true,"description":"null = unlimited"},"used":{"type":"integer"},"remaining":{"type":"integer","nullable":true},"exceeded":{"type":"boolean"},"resets_at":{"type":"string","format":"date-time","description":"Start of next UTC month"}}},"PriceGuideCatalogItem":{"type":"object","properties":{"slug":{"type":"string"},"brand":{"type":"string"},"label":{"type":"string"},"currency":{"type":"string"},"headlineMedianCents":{"type":"integer","nullable":true},"totalSampleSize":{"type":"integer"},"refreshedAt":{"type":"string","format":"date-time","nullable":true}}},"PriceBand":{"type":"object","properties":{"band":{"type":"string","enum":["high","mid","low"]},"label":{"type":"string"},"gradeRange":{"type":"string"},"currency":{"type":"string"},"valueLowCents":{"type":"integer","nullable":true},"valueMedianCents":{"type":"integer","nullable":true},"valueHighCents":{"type":"integer","nullable":true},"valueSampleSize":{"type":"integer"},"sellThrough":{"type":"number","nullable":true},"medianDaysToSell":{"type":"integer","nullable":true}}},"PriceGuideEntry":{"type":"object","properties":{"slug":{"type":"string"},"brand":{"type":"string"},"label":{"type":"string"},"categoryId":{"type":"string","nullable":true},"currency":{"type":"string"},"refreshedAt":{"type":"string","format":"date-time","nullable":true},"totalSampleSize":{"type":"integer"},"bands":{"type":"array","items":{"$ref":"#/components/schemas/PriceBand"}},"sellThroughScope":{"type":"string"}}},"GradeCompletedEvent":{"type":"object","description":"Delivered to your webhook_url when a grade finalizes. Verify X-GradeThread-Signature (HMAC-SHA256 hex of the raw body, secret = the delivering key's hash).","properties":{"event":{"type":"string","enum":["grade.completed"]},"data":{"type":"object","properties":{"submission_id":{"type":"string","format":"uuid"},"grade_report":{"type":"object","description":"Leaner than the REST grade_report.","properties":{"id":{"type":"string","format":"uuid"},"submission_id":{"type":"string","format":"uuid"},"overall_score":{"type":"number"},"grade_tier":{"type":"string"},"certificate_id":{"type":"string","nullable":true},"finalized_at":{"type":"string","format":"date-time"}}}}},"timestamp":{"type":"string","format":"date-time"}}}}}}