{"openapi":"3.1.0","info":{"title":"LogoTidy Agent API","version":"1.0.0","description":"Upload a logo; pay per cleanup using Stripe x402 v2 USDC on Base; review and download the complete kit. This is asynchronous paid processing. Check /status before submitting. Version 1 supports cleanup only, not logo generation or upgrades.","termsOfService":"https://www.logotidy.com/agents#terms","contact":{"name":"Marvento Labs LLC","email":"info@mlabs.ae","url":"https://www.logotidy.com/support"}},"servers":[{"url":"https://www.logotidy.com"}],"x-payment-status":"awaiting_payment_activation","x-x402":{"version":2,"network":"eip155:8453","asset":"USDC","provider":"Stripe","facilitator":"Coinbase Developer Platform","scheme":"exact","authorization":"EIP-3009"},"paths":{"/api/agent/v1/status":{"get":{"operationId":"getAgentCapabilities","summary":"Price, limits and actual payment activation status","security":[],"responses":{"200":{"description":"Current capabilities","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["available","awaiting_payment_activation"]},"payments":{"type":"object"},"price":{"type":"object"},"limits":{"type":"object"},"docs":{"type":"string","format":"uri"},"openapi":{"type":"string","format":"uri"},"termsVersion":{"type":"string"}}}}}}}}},"/api/agent/v1/jobs":{"post":{"security":[{"JobToken":[]}],"operationId":"createLogoCleanup","summary":"Validate PNG/JPEG and create a 15-minute immutable quote","description":"No charge. Maximum 3 MiB decoded image, 32 megapixels, single frame. Rate limited to 10 new jobs per IP/hour and 100 globally/hour. Save the client-generated token and Idempotency-Key before sending.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"Unique per upload/action. Reuse the key, token and identical body for retries."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateJob"}}}},"responses":{"200":{"description":"Original job returned for an identical retry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"201":{"description":"Validated source and quote; nextAction=pay","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid job token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Job not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicting retry or invalid job state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"Quote or file retention expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Image or request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Unsupported content type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid image or selection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited: Retry-After in seconds","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Payment not activated or temporarily unavailable. Never interpret a timeout as proof of non-payment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agent/v1/jobs/{id}/pay":{"post":{"security":[{"JobToken":[]}],"operationId":"payForLogoCleanup","summary":"Request x402 requirements or submit the signed payment","description":"Empty POST. First call returns HTTP 402 with PAYMENT-REQUIRED. Sign the exact offered requirements using an x402 v2 client and retry with PAYMENT-SIGNATURE plus the same Bearer token. Only the quoted amount, recipient, resource and USDC EIP-3009 authorization are accepted. Authorizations must expire within 300 seconds. The saved job itself is the payment idempotency boundary. A retry of a paid/pending job never requests another settlement. Poll its GET URL when payment is pending, even after a timeout.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"schema":{"type":"string"},"description":"Base64 x402 v2 PaymentPayload from the official client SDK."}],"responses":{"202":{"description":"Paid or reconciling; poll the job. Do not pay again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}},"headers":{"PAYMENT-RESPONSE":{"schema":{"type":"string"},"description":"Base64 settlement receipt when known."},"Retry-After":{"schema":{"type":"integer"},"description":"Suggested poll delay in seconds."}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid job token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required; no processing starts before settled funds and a confirmed Stripe receipt","content":{"application/json":{"schema":{"type":"object","required":["x402Version","resource","accepts"],"properties":{"x402Version":{"const":2},"resource":{"type":"object"},"accepts":{"type":"array","items":{"type":"object"}}}}}},"headers":{"PAYMENT-REQUIRED":{"schema":{"type":"string"},"description":"Base64 x402 v2 PaymentRequired JSON, matching the response body."}}},"404":{"description":"Job not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicting retry or invalid job state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"Quote or file retention expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Image or request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Unsupported content type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid image or selection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited: Retry-After in seconds","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Payment not activated or temporarily unavailable. Never interpret a timeout as proof of non-payment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agent/v1/jobs/{id}":{"get":{"security":[{"JobToken":[]}],"operationId":"getLogoCleanup","summary":"Private status, price, receipt, analysis and preview links","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Job, quality checks and nextAction","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid job token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Job not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicting retry or invalid job state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"Quote or file retention expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Image or request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Unsupported content type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid image or selection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited: Retry-After in seconds","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Payment not activated or temporarily unavailable. Never interpret a timeout as proof of non-payment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agent/v1/jobs/{id}/actions":{"post":{"security":[{"JobToken":[]}],"operationId":"reviewLogoCleanup","summary":"Resolve detected ambiguity, request a correction, or approve quality-checked artwork","description":"Inspect previews and analysis first. resolve/revise are allowed only in a relevant review state, with a combined limit of five submissions per job. Approval is permitted only after automated quality checks pass. Repeating an identical Idempotency-Key is safe and does not consume another correction.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"Unique per upload/action. Reuse the key, token and identical body for retries."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","additionalProperties":false,"required":["action"],"properties":{"action":{"const":"approve"}}},{"type":"object","additionalProperties":false,"required":["action","feedback"],"properties":{"action":{"const":"revise"},"feedback":{"type":"string","minLength":1,"maxLength":3000}}},{"type":"object","additionalProperties":false,"required":["action","layout","type","background","symbolBox","textBox"],"properties":{"action":{"const":"resolve"},"layout":{"enum":["horizontal","vertical"]},"type":{"enum":["combination","wordmark","emblem"]},"background":{"type":"string","pattern":"^#[a-fA-F0-9]{6}$"},"symbolBox":{"type":["object","null"],"additionalProperties":false,"required":["x","y","width","height"],"properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"width":{"type":"number","exclusiveMinimum":0,"maximum":1},"height":{"type":"number","exclusiveMinimum":0,"maximum":1}},"description":"Normalized coordinates; x+width and y+height must be <= 1."},"textBox":{"type":["object","null"],"additionalProperties":false,"required":["x","y","width","height"],"properties":{"x":{"type":"number","minimum":0,"maximum":1},"y":{"type":"number","minimum":0,"maximum":1},"width":{"type":"number","exclusiveMinimum":0,"maximum":1},"height":{"type":"number","exclusiveMinimum":0,"maximum":1}},"description":"Normalized coordinates; x+width and y+height must be <= 1."}},"description":"Combination logos require both boxes. Use null boxes for an intact emblem. Do not split an emblem's interior."}]}}}},"responses":{"202":{"description":"Action queued, or original action replayed","content":{"application/json":{"schema":{"type":"object","properties":{"jobId":{"type":"string","format":"uuid"},"queued":{"const":true},"replayed":{"type":"boolean"},"nextAction":{"const":"poll"}}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid job token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Job not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicting retry or invalid job state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"Quote or file retention expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Image or request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Unsupported content type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid image or selection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited: Retry-After in seconds","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Payment not activated or temporarily unavailable. Never interpret a timeout as proof of non-payment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/agent/v1/jobs/{id}/download":{"get":{"security":[{"JobToken":[]}],"operationId":"downloadLogoKit","summary":"Get a private ZIP URL after approval and completed exports","description":"Free repeat downloads during the 30-day window. Signed link expires in 120 seconds; request a fresh one if needed. ZIP includes transparent PNG/WebP, SVG, PDF and embroidery outline artwork, not DST/PES stitch files.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Temporary private download URL","content":{"application/json":{"schema":{"type":"object","required":["url","filename","expiresIn"],"properties":{"jobId":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"filename":{"type":"string"},"expiresIn":{"const":120}}}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing or invalid job token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Job not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Conflicting retry or invalid job state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"Quote or file retention expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Image or request too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"Unsupported content type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Invalid image or selection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited: Retry-After in seconds","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Payment not activated or temporarily unavailable. Never interpret a timeout as proof of non-payment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"JobToken":{"type":"http","scheme":"bearer","bearerFormat":"lt_<64 random lowercase hex characters>","description":"Client-generated 256-bit capability, unique to one job. Store securely; send only in Authorization. No account registration required."}},"schemas":{"CreateJob":{"type":"object","additionalProperties":false,"required":["image","mime","acceptTerms","termsVersion"],"properties":{"image":{"type":"string","contentEncoding":"base64","maxLength":4194304,"description":"Raw image bytes encoded in base64, no data URL prefix."},"mime":{"enum":["image/png","image/jpeg"]},"brandName":{"type":"string","maxLength":160,"default":"Logo"},"notes":{"type":"string","maxLength":2000,"default":""},"acceptTerms":{"const":true,"description":"The agent is authorized to accept the published service/site terms and request processing for its customer."},"termsVersion":{"const":"2026-09-11"}}},"Job":{"type":"object","required":["jobId","paymentStatus","price","nextAction"],"properties":{"jobId":{"type":"string","format":"uuid"},"paymentStatus":{"enum":["draft","settling","settled","paid","expired","deleted"]},"status":{"enum":["queued","processing","needs_input","review","approved","failed"]},"nextAction":{"enum":["pay","poll","check_payment_status","create_new_job","none","review_then_approve","resolve_or_revise","check_refund_status","download"]},"price":{"type":"object"},"quoteExpiresAt":{"type":"string","format":"date-time"},"filesExpireAt":{"type":["string","null"],"format":"date-time"},"termsVersion":{"type":"string"},"transaction":{"type":["string","null"]},"paymentIntent":{"type":["string","null"]},"refundStatus":{"type":["string","null"]},"analysis":{"type":["object","null"]},"quality":{"type":"object"},"sourceIssue":{"type":["object","null"]},"previews":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"filename":{"type":"string"},"url":{"type":"string","format":"uri"}}}},"links":{"type":"object"},"message":{"type":"string"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"fields":{"type":"array","items":{"type":"object"}}}},"docs":{"type":"string","format":"uri"}}}}}}