OpenAPI
The Aion API is documented in OpenAPI 3.1 format. Use the spec to generate clients, validate requests, or explore the API contract.
Spec
Download the OpenAPI spec:
Generate client
You can use the OpenAPI spec to generate a typed client. First, download the spec or reference it by URL:
curl -o openapi.yaml https://payaion.com/openapi.yamlJavaScript/TypeScript
npx openapi-typescript https://payaion.com/openapi.yaml -o payaion.d.tsPython
pip install openapi-python-client
openapi-python-client generate --url https://payaion.com/openapi.yamlGo
go install github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen@latest
oapi-codegen -package payaion openapi.yaml > payaion.goGood to know: For JavaScript/TypeScript, openapi-typescript generates a type-only file (.d.ts) — it contains no executable code. You still write HTTP requests yourself (with fetch, axios, etc.), but every response is fully typed instead of unknown.
Using the TypeScript types
After running the npx openapi-typescript command above, you get a payaion.d.ts file with an operations type that maps every API endpoint to its request and response shapes.
1. Extract the types you need
import type { operations } from "./payaion";
// Upload (POST /v1/aion/upload)
type UploadResponse =
operations["agentUpload"]["responses"]["202"]["content"]["application/json"];
// → { uploadId: string; status: "PENDING_UPLOAD"; statusUrl: string; downloadUrl: string; expiresAt: string }
type UploadError =
operations["agentUpload"]["responses"]["400"]["content"]["application/json"];
// → { error: { code: string; message: string; retryAfterSec?: number } }
// Status (GET /v1/upload/{id}/status)
type StatusResponse =
operations["agentUploadStatus"]["responses"]["200"]["content"]["application/json"];
// → { uploadId: string; status: "PENDING_UPLOAD"|"UPLOADING"|"READY"|"FAILED"|"DELETING"|"DELETED"; ready: boolean; ... }
// Fresh download URL (POST /v1/upload/{id}/download-url)
type DownloadUrlResponse =
operations["agentDownloadUrl"]["responses"]["200"]["content"]["application/json"];The path follows the pattern: operations["<operationId>"]["responses"]["<status>"]["content"]["application/json"]. Operation IDs match the spec: agentUpload, agentUploadStatus, agentDownloadUrl.
2. Use them with fetch
import type { operations } from "./payaion";
type UploadResponse =
operations["agentUpload"]["responses"]["202"]["content"]["application/json"];
async function upload(file: File, apiKey: string): Promise<UploadResponse> {
const body = new FormData();
body.append("file", file);
const res = await fetch("https://payaion-api.fly.dev/v1/aion/upload", {
method: "POST",
headers: { "X-Aion-Key": apiKey },
body,
});
if (!res.ok) throw new Error(`Upload failed: ${res.status}`);
const data: UploadResponse = await res.json();
// data.uploadId → string ✓
// data.status → "PENDING_UPLOAD" ✓
// data.statusUrl → string ✓
// data.downloadUrl → string ✓
// data.expiresAt → string ✓
return data;
}Without the generated types you would need to define these interfaces by hand or work with any. The types stay in sync with the API — re-run the command after spec updates.
Using the Python types
The openapi-python-client command from above generates a full client package with Pydantic models for every request and response. However, for multipart uploads you still call requests (or httpx) yourself. Below is a lightweight approach using TypedDict — no code generation needed.
1. Define response types
from __future__ import annotations
from typing import Literal, TypedDict
# Upload (POST /v1/aion/upload) — 202
class UploadResponse(TypedDict):
uploadId: str
status: Literal["PENDING_UPLOAD"]
statusUrl: str
downloadUrl: str
expiresAt: str # ISO 8601
# Error body (400, 401, 413, …)
class _ErrorDetail(TypedDict, total=False):
code: str
message: str
retryAfterSec: int # only on 429
class ApiError(TypedDict):
error: _ErrorDetail
# Status (GET /v1/upload/{id}/status) — 200
class StatusResponse(TypedDict, total=False):
uploadId: str
status: Literal["PENDING_UPLOAD", "UPLOADING", "READY", "FAILED", "DELETING", "DELETED"]
ready: bool
updatedAt: str
# Fresh download URL (POST /v1/upload/{id}/download-url) — 200
class DownloadUrlResponse(TypedDict):
uploadId: str
downloadUrl: str
expiresAt: str
ready: boolThese shapes match the OpenAPI spec exactly. If you prefer auto-generation, openapi-python-client creates equivalent Pydantic models for you.
2. Use them with requests
import requests
def upload(path: str, api_key: str) -> UploadResponse:
with open(path, "rb") as f:
resp = requests.post(
"https://payaion-api.fly.dev/v1/aion/upload",
headers={"X-Aion-Key": api_key},
files={"file": f},
)
resp.raise_for_status()
data: UploadResponse = resp.json()
# data["uploadId"] → str ✓
# data["downloadUrl"] → str ✓
# data["expiresAt"] → str ✓
return data
def check_status(upload_id: str, api_key: str) -> StatusResponse:
resp = requests.get(
f"https://payaion-api.fly.dev/v1/upload/{upload_id}/status",
headers={"X-Aion-Key": api_key},
)
resp.raise_for_status()
return resp.json()With TypedDict your editor autocompletes data["downloadUrl"] and catches typos at type-check time (mypy / pyright).
Base URL
All endpoints use the same base URL:
https://payaion-api.fly.devEndpoints covered
- POST /v1/aion/upload — Upload a file, get a download URL
- POST /v1/aion/upload-url — Upload from a URL (for bots & webhooks)
- GET /v1/upload/{id}/status — Check if the file is ready
- POST /v1/upload/{id}/download-url — Get a fresh download URL
The spec includes request/response schemas, authentication requirements, error formats, and all status codes.