{"components":{"schemas":{"ExecutionRequest":{"properties":{"code":{"description":"The Python to run. The only required field.","type":"string"},"files":{"additionalProperties":{"type":"string"},"description":"Files written into the in-memory `/tmp` before the run. Counted against the same `maxTmpBytes` budget the program writes against.","type":"object"},"limits":{"$ref":"#/components/schemas/Limits"},"maxTmpBytes":{"description":"Ceiling on the in-memory `/tmp`. Clamped to the server maximum, so it can only narrow.","type":"integer"},"modules":{"additionalProperties":{"type":"string"},"description":"Extra importable modules as `{dotted.name: source}`. How you ship code you do not want inlined into `code`.","type":"object"},"mounts":{"description":"Filesystems to attach, each your own bucket or container reached with your own credentials. Omit and the run sees only `/tmp`.","items":{"$ref":"#/components/schemas/Mount"},"type":"array"},"net":{"description":"Outbound endpoints this run may reach, `host:port`. The deployment sets the ceiling; this field is intersected with it, so it narrows and never widens. Omit it and the run gets the whole ceiling — absent means no extra restriction, not no network. An endpoint outside the ceiling is dropped rather than rejected, so the run fails at connect time with a catchable `OSError`. When the deployment's ceiling is empty, no run gets any network.","items":{"example":"api.openai.com:443","type":"string"},"type":"array"},"stdin":{"description":"Text fed to the program's stdin, split on newline into a queue of lines. `input()` pops one line per call and raises `EOFError` when the queue is empty, as CPython does at end of file. The optional prompt argument is written to stdout, like CPython.","type":"string"}},"required":["code"],"type":"object"},"ExecutionResponse":{"properties":{"cpuMicros":{"description":"CPU microseconds consumed. A diagnostic, not the bill: it varies with hardware and with whoever else is on the machine, so it is neither predictable nor auditable.","type":"integer"},"error":{"description":"The Python error, when the run raised. The program raised it; see `resultError` for a run that finished and only failed to render its value.","type":"string"},"executionId":{"format":"uuid","type":"string"},"instructions":{"description":"**What you are billed.** Interpreted instructions, plus a per-element charge for builtins that loop, plus fixed costs for blocking calls. Deterministic: the same program on the same input always bills the same, so you can predict it and audit it. A blocking call is charged when it is attempted, even when it is refused. A program that does not compile bills nothing. No run exceeds the per-run instruction cap, whatever the balance.","type":"integer"},"result":{"description":"The value of the last expression statement in `code`, as `repr()` prints it — the rule a notebook cell follows. `2 + 2` yields `\"4\"`; `x = 2 + 2` yields nothing, because an assignment is not an expression; `print(x)` yields nothing, because it evaluates to None. Absent whenever there is no such value. An object of your own class renders through its `__repr__`, and as `<ClassName object>` when it has none — which is also what you get when its `__repr__` raised, with `resultError` carrying the exception. Capped at 65536 bytes: this is a field of a JSON response, not a stream. Going past the cap sets `resultTruncated` and never changes `status`, and the program itself never sees the cap — `len(repr(x))` measured inside the run is the whole length.","type":"string"},"resultError":{"description":"The exception raised while rendering `result` — a `__repr__` of yours that raised. Its presence does NOT mean the program failed, and this is what separates it from `error`, which has the same `\"ValueError: nope\"` shape: `error` means the program raised, `resultError` means the program finished and rendering the value it finished with raised. Inside a running program that exception is ordinary and catchable; once the run is over there is no program left to catch it, so the run stays `completed`, `result` falls back to the rendering that needs no Python, and the exception is reported here.","type":"string"},"resultTruncated":{"description":"Present and `true` only when `result` hit the 65536-byte cap and was cut, so a prefix is never read as the whole value. The cut lands on a character boundary. Omitted when nothing was cut.","type":"boolean"},"status":{"description":"`halted` means a limit stopped the run — the instruction ceiling, the timeout, the heap, or recursion depth. It cannot be caught by guest code.","enum":["completed","failed","halted"],"type":"string"},"stdout":{"type":"string"}},"required":["executionId","status","stdout","instructions"],"type":"object"},"Limits":{"properties":{"maxInstructions":{"description":"Instruction ceiling for the run. It can only narrow: the run stops at the smallest of this, the server ceiling, the per-run cap and your remaining balance, and `status` comes back `halted`.","type":"integer"},"timeoutMs":{"description":"Wall-clock ceiling for this run. Clamped to the deployment's own timeout, so it can only narrow it.","type":"integer"}},"type":"object"},"Mount":{"properties":{"account":{"description":"`azure-blob` storage account.","type":"string"},"at":{"description":"Absolute path the mount appears at. May not be `/tmp` or inside it, may not contain `..`, and may not nest inside another mount.","example":"/data","type":"string"},"bucket":{"description":"`s3`/`gcs` bucket name.","type":"string"},"container":{"description":"`azure-blob` container.","type":"string"},"credentials":{"$ref":"#/components/schemas/MountCredentials"},"endpoint":{"description":"Override the provider endpoint. Required for R2, MinIO and B2. Must be https, must resolve to a public address, and redirects are not followed.","example":"https://abc123.r2.cloudflarestorage.com","type":"string"},"prefix":{"description":"Prepended to every key, so a mount can expose one subtree of a bucket. `at: \"/data\"` with this prefix maps `/data/in.csv` to key `runs/42/in.csv`.","example":"runs/42/","type":"string"},"provider":{"description":"`s3` covers AWS S3, Cloudflare R2, MinIO, Backblaze B2, DigitalOcean Spaces and Wasabi. `gcs` is Google Cloud Storage via its S3-compatible API, authenticated with an HMAC key.","enum":["s3","gcs","azure-blob"],"type":"string"},"readOnly":{"default":false,"description":"Refuse every write, append, delete and rename under this mount, before any request leaves this service.","type":"boolean"},"region":{"default":"us-east-1","type":"string"}},"required":["at","provider"],"type":"object"},"MountCredentials":{"description":"Sent over TLS, used for the run, and never stored, logged or echoed back. Guest code cannot read them: there is no syscall that exposes them and they are not placed in the environment. Omit entirely for a public bucket.","properties":{"accessKey":{"description":"`azure-blob` Shared Key.","type":"string"},"accessKeyId":{"description":"`s3`, `gcs` (HMAC key id).","type":"string"},"sasToken":{"description":"`azure-blob`, with or without the leading `?`.","type":"string"},"secretAccessKey":{"description":"`s3`, `gcs` (HMAC secret).","type":"string"},"sessionToken":{"description":"`s3`, for temporary STS credentials.","type":"string"}},"type":"object"}},"securitySchemes":{"bearerAuth":{"scheme":"bearer","type":"http"}}},"info":{"description":"Run untrusted Python in a sealed sandbox. A run gets no filesystem, no process and no environment. Outbound network is whatever this deployment allows, narrowed by what the request asks for. Storage is yours: mount your own S3, Google Cloud Storage or Azure Blob container and the run reads and writes there with your credentials. Nothing is stored on our side.","title":"Sucuri Execution Service","version":"0.2.0"},"openapi":"3.0.3","paths":{"/api/executions":{"post":{"description":"Runs the supplied Python to completion and returns the result inline. Requires `Authorization: Bearer <api-key>` — a per-account key, see `GET /app`.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecutionRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecutionResponse"}}},"description":"The program ran. It may still have raised — check `status`."},"400":{"description":"Malformed body, or a mount that cannot be accepted (bad mount point, overlapping mounts, an endpoint this service will not connect to)."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Balance is at or below zero. The body carries a `topUp` URL."},"503":{"description":"Temporarily unable to meter the run, so it was not executed and nothing was charged. Retry."}},"security":[{"bearerAuth":[]}],"summary":"Run code"}}}}