Storage

Quote a hosted upload (step 1 of the upload flow)

Requires scope files:read. Prices an upload of exactly sizeBytes against the allowlisted provider and current market policy. The quote is valid for 60 seconds and must be redeemed by POST /api/v1/files with the X-Kepto-Quote-Id header. Price, provider, and duration are server-controlled; supplying them fails with 400 UNSAFE_QUOTE_FIELD.

POST/api/v1/files/quoteTry it
iNote
Requires a key with the files:read scope, sent as Authorization: Bearer <api-key>. Keys missing the scope are rejected with 403 — see Authentication.
iNote
Part of the three-step upload flow: quote the upload with POST /api/v1/files/quote, store the bytes against the quote with POST /api/v1/files, then poll GET /api/v1/jobs/{jobId} until the job completes.

Body

application/json QuoteRequestrequired

Example body
{
  "sizeBytes": 0,
  "contentMode": "public",
  "replicas": 1
}

Errors

CodeMeaning
400UNSAFE_QUOTE_FIELD when price, provider, or duration is supplied; INVALID_QUOTE for malformed sizeBytes or replicas.
401Invalid or missing API key.
403The API key lacks the required scope for this operation.
409PROVIDER_CAPACITY when no allowlisted active provider has capacity or more than one replica is requested.
cURL
curl -X POST https://gateway.kepto.xyz/api/v1/files/quote \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "sizeBytes": 0,
    "contentMode": "public",
    "replicas": 1
  }'
200 · application/json
{
  "quoteId": "string",
  "market": "string",
  "provider": "string",
  "rateWeiPerGiB30d": "string",
  "sizeBytes": 0,
  "contentMode": "public",
  "durationSeconds": 2592000,
  "replicas": 0,
  "totalPriceWei": "string",
  "collateralWei": "string",
  "slashPerFaultWei": "string",
  "expiresAt": "2026-01-01T00:00:00Z"
}