{"openapi":"3.1.0","info":{"title":"Run it by API","version":"0.1.0","description":"Get structured data or a decision from a human through a link. Same operations as the MCP server at /mcp."},"servers":[{"url":"https://runitby.app/v1"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"}}},"security":[{"bearer":[]}],"paths":{"/requests":{"post":{"operationId":"createRequest","summary":"Ask a human: create a form or approval and get the link(s) to send","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"mode":{"type":"string","enum":["form","approval"]},"title":{"type":"string","minLength":1,"maxLength":120},"requester":{"description":"How your agent introduces itself, e.g. \"Ava (the Acme refunds agent)\".","type":"string","maxLength":120},"audience":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","const":"open"},"maxSubmissions":{"default":1,"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["kind"]},{"type":"object","properties":{"kind":{"type":"string","const":"named"},"recipients":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"phone":{"type":"string","maxLength":40}},"required":["name"]}}},"required":["kind","recipients"]}]},"schema":{"description":"JSON Schema (type object) for forms. See the supported subset in the docs.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"sections":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":80},"fields":{"type":"array","items":{"type":"string"}}},"required":["title","fields"]}},"approval":{"type":"object","properties":{"reason":{"type":"string","minLength":1,"maxLength":300,"description":"What you are asking approval for, e.g. \"Refund order #4821, $1,200\"."},"detail":{"description":"One or two sentences of context shown under the reason.","type":"string","maxLength":1000},"options":{"description":"Decision labels; the first one counts as approval. Default [\"Approve\", \"Decline\"].","minItems":2,"maxItems":4,"type":"array","items":{"type":"string","minLength":1,"maxLength":40}},"allowComment":{"default":true,"type":"boolean"},"policy":{"default":"all","anyOf":[{"type":"string","enum":["any","all","majority"]},{"type":"object","properties":{"n":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["n"]}]},"showOthers":{"default":false,"description":"Show each approver where the others stand. Off by default.","anyOf":[{"type":"boolean","const":false},{"type":"string","enum":["names","counts"]}]},"verify":{"default":false,"description":"\"email\": recipients confirm a 6-digit code before deciding. Use for money, access or deletion.","anyOf":[{"type":"boolean","const":false},{"type":"string","const":"email"}]}},"required":["reason"]},"theme":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"expiresIn":{"description":"Default 7d, at most 90d.","anyOf":[{"type":"string","pattern":"^\\d+[mhd]$"},{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}]},"sendEmail":{"default":false,"description":"Email each named recipient that has an email their link now. Off by default: then you deliver the links yourself.","type":"boolean"},"notifyEmail":{"type":"string","enum":["off","each","complete"],"description":"Email the account owner (your user) a summary and a dashboard link: \"each\" on every answer (the first 100, then only the end), \"complete\" once when the request completes or expires. Left out: the account's default from the dashboard (\"off\" unless changed)."},"webhookUrl":{"type":"string","format":"uri"},"locale":{"description":"Language of the hosted page, e.g. \"en\" or \"es-AR\".","type":"string","pattern":"^[a-z]{2}(-[A-Z]{2})?$"},"metadata":{"description":"Returned untouched in every webhook and getStatus.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["mode","title","audience"]}}}},"responses":{"201":{"description":"requestId, url (open audience) or links[] (named, each with email: sent | failed | no address | off), expiresAt"},"400":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"401":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"429":{"description":"Over 60 creations a minute, or the plan's monthly requests are used up","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}}},"get":{"operationId":"listRequests","summary":"Requests you created, newest first","parameters":[{"name":"mode","in":"query","schema":{"type":"string","enum":["form","approval"]}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending","partial","complete","expired","closed"]}},{"name":"limit","in":"query","schema":{"default":20,"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"requests[] and nextCursor"}}}},"/requests/preview":{"post":{"operationId":"previewRequest","summary":"Screenshots (390 and 1280 px) and lint of what a recipient will see; nothing is created","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"mode":{"type":"string","enum":["form","approval"]},"title":{"type":"string","minLength":1,"maxLength":120},"requester":{"description":"How your agent introduces itself, e.g. \"Ava (the Acme refunds agent)\".","type":"string","maxLength":120},"schema":{"description":"JSON Schema (type object) for forms. See the supported subset in the docs.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"sections":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":80},"fields":{"type":"array","items":{"type":"string"}}},"required":["title","fields"]}},"approval":{"type":"object","properties":{"reason":{"type":"string","minLength":1,"maxLength":300,"description":"What you are asking approval for, e.g. \"Refund order #4821, $1,200\"."},"detail":{"description":"One or two sentences of context shown under the reason.","type":"string","maxLength":1000},"options":{"description":"Decision labels; the first one counts as approval. Default [\"Approve\", \"Decline\"].","minItems":2,"maxItems":4,"type":"array","items":{"type":"string","minLength":1,"maxLength":40}},"allowComment":{"default":true,"type":"boolean"},"policy":{"default":"all","anyOf":[{"type":"string","enum":["any","all","majority"]},{"type":"object","properties":{"n":{"type":"integer","minimum":1,"maximum":9007199254740991}},"required":["n"]}]},"showOthers":{"default":false,"description":"Show each approver where the others stand. Off by default.","anyOf":[{"type":"boolean","const":false},{"type":"string","enum":["names","counts"]}]},"verify":{"default":false,"description":"\"email\": recipients confirm a 6-digit code before deciding. Use for money, access or deletion.","anyOf":[{"type":"boolean","const":false},{"type":"string","const":"email"}]}},"required":["reason"]},"theme":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"locale":{"description":"Language of the hosted page, e.g. \"en\" or \"es-AR\".","type":"string","pattern":"^[a-z]{2}(-[A-Z]{2})?$"},"viewports":{"default":[390,1280],"description":"Screenshot widths: 390 (phone) and/or 1280 (desktop).","minItems":1,"maxItems":2,"type":"array","items":{"anyOf":[{"type":"number","const":390},{"type":"number","const":1280}]}},"sampleData":{"description":"Answers to prefill, to see how filled fields look.","type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["mode","title"]}}}},"responses":{"200":{"description":"previewUrl, screenshots[] ({ viewport, png base64 }), lint[]"},"400":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}}}},"/requests/{id}":{"get":{"operationId":"getRequest","summary":"Status, verdict and every answer so far; ?wait=N holds until something changes","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"wait","in":"query","schema":{"description":"Seconds to wait for a new answer or a status change before returning (at most 25). Returns at once when something changes.","type":"integer","minimum":0,"maximum":25}}],"responses":{"200":{"description":"Status"},"404":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}}},"patch":{"operationId":"updateRequest","summary":"Edit content until the first response; add recipients or set a new expiry until it closes","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":120},"schema":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"sections":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":80},"fields":{"type":"array","items":{"type":"string"}}},"required":["title","fields"]}},"reason":{"description":"New approval reason.","type":"string","minLength":1,"maxLength":300},"theme":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"expiresIn":{"anyOf":[{"type":"string","pattern":"^\\d+[mhd]$"},{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}]},"notifyEmail":{"type":"string","enum":["off","each","complete"],"description":"Email the account owner (your user) a summary and a dashboard link: \"each\" on every answer (the first 100, then only the end), \"complete\" once when the request completes or expires. Left out: the account's default from the dashboard (\"off\" unless changed)."},"addRecipients":{"maxItems":50,"type":"array","items":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"phone":{"type":"string","maxLength":40}},"required":["name"]}}}}}}},"responses":{"200":{"description":"requestId and links[]"},"400":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"404":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"409":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}}},"delete":{"operationId":"closeRequest","summary":"Stop accepting answers","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"{ ok: true }"},"404":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}}}},"/requests/{id}/remind":{"post":{"operationId":"remind","summary":"Email the link again to pending named recipients (once per 24 h each)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"recipientIds":{"description":"Only these recipients; default every pending one.","maxItems":50,"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"sent[] and skipped[]"},"400":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"404":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"409":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}}}},"/requests/{id}/status":{"get":{"operationId":"getStatus","summary":"Same as GET /requests/{id}","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"wait","in":"query","schema":{"description":"Seconds to wait for a new answer or a status change before returning (at most 25). Returns at once when something changes.","type":"integer","minimum":0,"maximum":25}}],"responses":{"200":{"description":"Status"},"404":{"description":"Readable error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"problems":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}}}}}}