Platform

API

One key, one balance, every service. Outputs come back as artifacts you can pass straight into the next call.

YOUR KEY

Sign in with your 4i account to create a key.

FOR CODE AGENTS

One paste with everything a coding agent (Claude Code, Cursor, Copilot…) needs: base URL, a key placeholder, endpoints, response shapes and error rules. The agent reads the current services from GET /services.

Preview
# 4i Platform API — integration brief

Use this to integrate the 4i Platform API: one REST API for image, video, audio and text AI services. Outputs are artifacts whose ids can be passed straight into the next service.

## Configuration
- Base URL: https://platform.4i.app/api/v1
- API key: <YOUR_4I_API_KEY>
- Auth header on every call (except GET /services): `Authorization: Bearer <YOUR_4I_API_KEY>`
- Store the key as a server-side secret/env var (e.g. `FOURI_API_KEY`). It acts as the account and spends its credits — never ship it to a browser or commit it.
- The key is not included here: ask the developer for it (they get it at the API page of platform.4i.app).
- JSON in, JSON out. CORS is open (`*`).

## Endpoints
- `GET /services` — catalog (no key). Filters: `?output=image|video|audio|text`, `?provider=`, `?censorship=none|low|medium|high|unknown` (unknown = not confirmed yet) (comma lists).
- `POST /run` — run one service. Body: `{ "service": "<id>", "input": { "prompt": "…", "image": "img_…" | "https://…", "video": …, "audio": …, "text": … }, "params": { … }, "session": "ses_…" (optional) }`
- `GET /runs/{id}` — a run and its outputs. Reading it advances a running async run.
- `GET /runs?service=&limit=` — recent runs.
- `POST /uploads` — multipart field `file` (image, video, audio, text; 50 MB max) → artifact `{ "id": "img_…", "kind": "image", "url": "https://…" }`.
- `GET /artifacts/{id}` — an artifact's `url` (media) or `text`.
- `GET|POST /sessions`, `GET|PATCH|DELETE /sessions/{id}` — group runs into threads (optional).
- `GET /me` — the key's account and credit balance.

## Choosing a service
The catalog changes often, so it is not listed here. Call `GET https://platform.4i.app/api/v1/services` (no key needed) to see what is available, and look services up from it rather than hard-coding a list. Each entry in `services` has:
- `id` (pass it as `service`), `name`, `provider` (model maker), `task`, `output` (image|video|audio|text), `async`
- `prompt`: `required` | `optional` | `none`; `slots`: media inputs `[{ "kind": "image"|"video"|"audio"|"text", "required": true|false }]`; `requiresAny`: at least one of these inputs must be sent
- `params`: `[{ "name", "type", "options", "min", "max", "default" }]`
- `price` credits per `unit`, `censorship` (content filter level), `avgMs` (typical run time, or null)

## Run object
```json
{ "id": "run_…", "object": "run", "status": "running|succeeded|failed", "service": "<id>",
  "input": { … }, "params": { … },
  "outputs": [{ "id": "img_…", "kind": "image", "url": "https://…" }],
  "artifact_id": "img_…", "estimate": 0.02, "cost": 0.02, "error": null,
  "created_at": "…", "finished_at": "…", "duration_ms": 4210, "balance": 12.5 }
```
Text outputs are artifacts too (`txt_…`); fetch `GET /artifacts/{id}` for the text, or pass the id on as `input.text`.

## Rules to code against
- Inputs: `prompt` is a string; `image`/`video`/`audio`/`text` are an artifact id you own (`img_…`, `vid_…`, `aud_…`, `txt_…`) or a public https URL. Only send the inputs the service's catalog entry lists.
- Params outside a service's list are ignored; omitted params use their defaults.
- Async services (video) answer `"status": "running"`. Poll `GET /runs/{id}` every 5–10 s until `succeeded` or `failed`. Every run has a deadline (usually 10 min, longer for some video models); past it the run is failed and refunded.
- Billing: the estimate is reserved when a run starts and settled to the real cost when it ends. Failed runs are fully refunded.
- A provider/model failure is NOT an HTTP error: you get HTTP 200 with `"status": "failed"` and a human-readable `error`. Always check `status`.
- HTTP errors (`{ "statusMessage": "…" }`): 400 bad input, 401 missing/invalid key, 402 not enough credits (top up at https://platform.4i.app/?buy=credits), 404 unknown service/run/artifact, 429 rate limited (back off and retry).
- Output URLs are public https links; download/copy them if you need them long-term.

## Example
```bash
curl https://platform.4i.app/api/v1/services?output=image

curl https://platform.4i.app/api/v1/run \
  -H "Authorization: Bearer <YOUR_4I_API_KEY>" -H "Content-Type: application/json" \
  -d '{ "service": "prunaai/p-image", "input": { "prompt": "studio photo of a cream leather sneaker" }, "params": { "aspect_ratio": "1:1" } }'
```

Quickstart

Base URL https://platform.4i.app/api/v1. Send Authorization: Bearer 4i_… on every call. Prices are in credits, reserved when a run starts and settled to the real cost when it ends; failed runs are refunded.

POST/run— run a service
curl https://platform.4i.app/api/v1/run -H "Authorization: Bearer $FOURI_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "service": "prunaai/p-image",
        "input": { "prompt": "studio photo of a cream leather sneaker" },
        "params": { "aspect_ratio": "1:1" } }'

→ { "id": "run_…", "status": "succeeded", "artifact_id": "img_…",
    "outputs": [{ "id": "img_…", "kind": "image", "url": "https://…" }], "cost": 0.01 }
POST/run— feed an output into the next service
curl https://platform.4i.app/api/v1/run -H "Authorization: Bearer $FOURI_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "service": "bria/remove-background", "input": { "image": "img_…" } }'
POST/uploads— bring your own file
curl https://platform.4i.app/api/v1/uploads -H "Authorization: Bearer $FOURI_KEY" -F file=@photo.jpg

→ { "id": "img_…", "kind": "image", "url": "https://…" }

Reference

GET/servicesThe catalog: ids, inputs, params and prices. No key needed.
POST/runRun one service. Video runs return "running" — poll the run.
GET/runs/{id}A run and its outputs. Reading it advances a running video.
GET/runs?service=&limit=Your recent runs.
POST/uploadsMultipart "file" → an artifact (image, video, audio, text). 50 MB max.
GET/artifacts/{id}An artifact's url or text.
GET POST/sessionsList or create sessions (the playground's threads).
GET PATCH DELETE/sessions/{id}A session with its runs; rename; remove from the list.
GET/meThe key's account and balance.

Inputs: prompt plus any of image, video, audio, text — each an artifact id you own (img_…) or a public https URL. Each service lists its inputs and params in the catalog and in GET /api/v1/services.