Guest Machines
API referenceRuns

Upload an artifact

POST/api/v1/artifacts

Upload one immutable artifact for later attachment to a run. Send the file bytes directly as application/octet-stream; do not wrap them in JSON, base64, or multipart form data. A 201 means the server received exactly X-Upload-Size bytes, verified X-Content-SHA256, durably stored the bytes, and made the returned artifact ready for use.

Idempotency-Key is mandatory. An exact replay of a completed upload returns the same artifact without storing a second copy. Reusing the key with different metadata, size, or checksum answers 409. An upload still in progress also answers 409 and sets Retry-After; after a failed or deleted upload, use a new key. Terminal key evidence remains conflicting for at least 30 days and until blob cleanup is confirmed. It is then purged, so an old key is not a permanent operation identifier.

Caller uploads are run inputs, not run-produced outputs. Uploading a file never satisfies an output requirement or creates run verification, checkpoint, or webhook evidence.

Content-Length is optional, so chunked transfer is supported. When a client sends it, the value must equal X-Upload-Size; the server always enforces the declared size while streaming.

Required access

Credentials: service principal, delegated token, user session

Scope: runs:create

A direct user-session or delegated-token upload is private to that user. A service-principal upload is shared with its organization because a service principal carries no user identity. A service principal with a resource allowlist cannot upload because no artifact UUID exists to allowlist before creation. Direct viewers cannot upload.

Authorization

AuthorizationBearer <token>

An organization-owned automation key, prefixed gsmc_sk_. Already bound to one organization, so it needs no X-Org-Id header. It carries no user identity: it never reaches a private resource however it is scoped, and a run it starts has no user for an interactive tool to reach.

In: header

Query Parameters

file_name*File Name

Required display filename, including the extension used to derive file-category limits and the safe served media type. Send a basename only, never a path.

Length1 <= length <= 255
description?|

Optional human-readable description, at most 2,000 characters.

Header Parameters

X-Upload-Size*X-Upload-Size

Exact positive byte length of the raw request body. The server rejects both shorter and longer streams and makes no artifact ready when the value does not match.

Range1 <= value
X-Content-SHA256*X-Content-Sha256

Lowercase 64-character hexadecimal SHA-256 digest of the exact raw request body. The server calculates it while streaming and rejects a mismatch before the artifact becomes ready.

Match^[0-9a-f]{64}$
Idempotency-Key*Idempotency-Key

Makes this upload retry-safe. Generate one stable value per intended file and reuse it only when retrying that exact upload. Keys are scoped to the caller and active organization, so unrelated credentials cannot adopt one another's upload. Reusing a key with different filename, description, byte length, or checksum answers 409.

Length1 <= length <= 255
X-Org-Id?|

Selects the active organization for a direct user session that has more than one membership. Service-principal keys and delegated tokens are each bound to one organization and ignore it.

Request Body

application/octet-stream

The exact file bytes. The stream must contain precisely the number of bytes declared by X-Upload-Size and hash to the lowercase SHA-256 digest declared by X-Content-SHA256.

TypeScript Definitions

Use the request body type in TypeScript.

body*file
Formatbinary

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/api/v1/artifacts?file_name=string" \  -H "Authorization: Bearer $GUEST_MACHINES_API_KEY" \  -H "X-Upload-Size: 5" \  -H "X-Content-SHA256: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" \  -H "Idempotency-Key: 9f8c2b7a-1d3e-4f5a-8b6c-2e1d0a9f8c7b" \  -H "Content-Type: application/octet-stream" \  -d 'string'
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "producer_run_id": 0,  "root_run_id": 0,  "chat_message_id": 0,  "visibility": "org_shared",  "status": "deleted",  "source_kind": "inline",  "file_name": "string",  "media_type": "string",  "file_size": 0,  "sha256": "string",  "description": "string",  "is_primary": true,  "metadata": {},  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}
{  "detail": "string",  "error_code": "string",  "request_id": "string"}
{  "detail": "string",  "error_code": "string",  "request_id": "string"}
{  "detail": "string",  "error_code": "string",  "request_id": "string"}
{  "detail": "string",  "error_code": "string",  "request_id": "string"}
{  "detail": "string",  "error_code": "string",  "request_id": "string"}
{  "detail": "string",  "error_code": "string",  "request_id": "string"}
{  "detail": "string",  "error_code": "string",  "request_id": "string"}
{  "detail": "string",  "error_code": "string",  "request_id": "string"}
{  "detail": "string",  "error_code": "string",  "request_id": "string"}
{  "detail": "string",  "error_code": "string",  "request_id": "string"}