Appearance
API Endpoints
Base URL: https://api.atiru.io
Authentication: Authorization: Bearer <api_key> or X-Api-Key: <api_key>
Auth
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /auth/register | No | Register |
| POST | /auth/login | No | Login |
| POST | /auth/forgot-password | No | Request password reset |
| POST | /auth/api-keys | JWT only | Create API key |
| GET | /auth/api-keys | JWT only | List API keys |
| DELETE | /auth/api-keys/:id | JWT only | Revoke API key |
POST /auth/register
Code example
bash
curl -X POST "https://api.atiru.io/auth/register" \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"your_password","redirect_to":"https://app.example.com/auth/confirm-success"}'javascript
const res = await fetch('https://api.atiru.io/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'you@example.com',
password: 'your_password',
redirect_to: 'https://app.example.com/auth/confirm-success',
}),
})
const data = await res.json()python
import requests
res = requests.post(
'https://api.atiru.io/auth/register',
json={
'email': 'you@example.com',
'password': 'your_password',
'redirect_to': 'https://app.example.com/auth/confirm-success',
},
)
data = res.json()Request
- Body
json
{
"email": "you@example.com",
"password": "your_password",
"redirect_to": "https://app.example.com/auth/confirm-success"
}| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Email address | |
| password | string | Yes | Min 6 characters |
| redirect_to | string | No | URL after email confirmation |
Response
- 201 — Success
json
{
"message": "Check your email to confirm your account.",
"user": {
"id": "uuid",
"email": "you@example.com"
}
}- 400 — Bad request (e.g. invalid email, short password)
POST /auth/login
Code example
bash
curl -X POST "https://api.atiru.io/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"your_password"}'javascript
const res = await fetch('https://api.atiru.io/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: 'you@example.com', password: 'your_password' }),
})
const { user, session } = await res.json()
const accessToken = session.access_tokenpython
import requests
res = requests.post(
'https://api.atiru.io/auth/login',
json={'email': 'you@example.com', 'password': 'your_password'},
)
data = res.json()
access_token = data['session']['access_token']Request
- Body
json
{
"email": "you@example.com",
"password": "your_password"
}Response
- 200 — Success
json
{
"user": {
"id": "uuid",
"email": "you@example.com",
"created_at": "2024-01-15T12:00:00.000Z",
"updated_at": "2024-01-15T12:00:00.000Z"
},
"session": {
"access_token": "eyJ...",
"refresh_token": "...",
"expires_in": 3600,
"expires_at": 1705334400,
"token_type": "bearer"
}
}- 401 — Invalid credentials
- 403 — Email not verified. Body includes
code: "EMAIL_NOT_VERIFIED".
POST /auth/api-keys
Requires JWT (login token). API key auth returns 403.
Code example
bash
curl -X POST "https://api.atiru.io/auth/api-keys" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Production server"}'javascript
const res = await fetch('https://api.atiru.io/auth/api-keys', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: 'Production server' }),
})
const { id, key, key_prefix, name, created_at } = await res.json()python
import requests
res = requests.post(
'https://api.atiru.io/auth/api-keys',
headers={'Authorization': 'Bearer YOUR_JWT_TOKEN'},
json={'name': 'Production server'},
)
data = res.json()Request
- Body
json
{
"name": "Production server"
}| Field | Type | Required | Description |
|---|---|---|---|
| name | string | No | Label for the API key |
Response
- 201 — Success. The
keyvalue is returned only once; store it securely.
json
{
"id": "uuid",
"key": "atiru_xxxxxxxxxxxx",
"key_prefix": "atiru_xxxx",
"name": "Production server",
"created_at": "2024-01-15T12:00:00.000Z"
}- 401 — Unauthorized
- 403 — API key cannot manage API keys (use JWT)
GET /auth/api-keys
Code example
bash
curl -X GET "https://api.atiru.io/auth/api-keys" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"javascript
const res = await fetch('https://api.atiru.io/auth/api-keys', {
headers: { 'Authorization': 'Bearer YOUR_JWT_TOKEN' },
})
const { api_keys } = await res.json()python
import requests
res = requests.get(
'https://api.atiru.io/auth/api-keys',
headers={'Authorization': 'Bearer YOUR_JWT_TOKEN'},
)
data = res.json()
api_keys = data['api_keys']Request
- No query params or body.
Response
- 200 — Success
json
{
"api_keys": [
{
"id": "uuid",
"key_prefix": "atiru_xxxx",
"name": "Production server",
"created_at": "2024-01-15T12:00:00.000Z",
"last_used_at": "2024-01-16T10:30:00.000Z"
}
]
}- 401 — Unauthorized
- 403 — API key cannot list API keys (use JWT)
DELETE /auth/api-keys/:id
Code example
bash
curl -X DELETE "https://api.atiru.io/auth/api-keys/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"javascript
await fetch('https://api.atiru.io/auth/api-keys/550e8400-e29b-41d4-a716-446655440000', {
method: 'DELETE',
headers: { 'Authorization': 'Bearer YOUR_JWT_TOKEN' },
})python
import requests
requests.delete(
'https://api.atiru.io/auth/api-keys/550e8400-e29b-41d4-a716-446655440000',
headers={'Authorization': 'Bearer YOUR_JWT_TOKEN'},
)Request
- Path:
:id— API key UUID.
Response
- 204 — No body. Key revoked.
- 401 — Unauthorized
- 403 — API key cannot revoke (use JWT)
- 404 — Key not found
Files
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /files | Yes | Upload file |
| GET | /files | Yes | List files |
| GET | /files/:id | Yes | Get one file by file_id |
| DELETE | /files/:id | Yes | Delete file |
| POST | /files/bulk-delete | Yes | Bulk delete (max 100 IDs) |
POST /files
Code example
bash
curl -X POST "https://api.atiru.io/files" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: image/png" \
-H "x-file-name: example.png" \
--data-binary @/path/to/example.pngjavascript
const fileBuffer = await readFile('./example.png')
const res = await fetch('https://api.atiru.io/files', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'image/png',
'x-file-name': 'example.png',
},
body: fileBuffer,
})
const { file, message } = await res.json()python
import requests
with open('example.png', 'rb') as f:
res = requests.post(
'https://api.atiru.io/files',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'image/png',
'x-file-name': 'example.png',
},
data=f.read(),
)
data = res.json()
print(data['file']['public_url'])Request
- Query
| Param | Type | Default | Description |
|---|---|---|---|
| isPublic | boolean | true | Set to false for private uploads |
- Headers:
Content-Type(required, MIME type),x-file-name(optional) - Body: Raw binary (file bytes)
Response
- 201 — Success
json
{
"file": {
"id": "uuid",
"user_id": "uuid",
"file_id": "abc123",
"name": "example.png",
"content_type": "image/png",
"size": 12345,
"public_url": "https://cdn.atiru.io/m/abc123",
"default_url": "https://cdn.atiru.io/m/abc123",
"default_download_url": "https://cdn.atiru.io/d/abc123",
"public_download_url": "https://cdn.atiru.io/d/abc123",
"created_at": "2024-01-15T12:00:00.000Z",
"is_public": true
},
"message": "File uploaded"
}- 400 — Content-Type not allowed
- 401 — Unauthorized
- 403 — Trial ended, storage limit, or file count limit
- 413 — File too large (
code: "FILE_TOO_LARGE")
GET /files
Code example
bash
curl -X GET "https://api.atiru.io/files" \
-H "Authorization: Bearer YOUR_API_KEY"javascript
const res = await fetch('https://api.atiru.io/files', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
})
const { files } = await res.json()python
import requests
res = requests.get(
'https://api.atiru.io/files',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
files = res.json()['files']Request
- No query params or body.
Response
- 200 — Success
json
{
"files": [
{
"id": "uuid",
"user_id": "uuid",
"file_id": "abc123",
"name": "example.png",
"content_type": "image/png",
"size": 12345,
"public_url": "https://cdn.atiru.io/m/abc123",
"default_url": "https://cdn.atiru.io/m/abc123",
"default_download_url": "https://cdn.atiru.io/d/abc123",
"public_download_url": "https://cdn.atiru.io/d/abc123",
"created_at": "2024-01-15T12:00:00.000Z",
"is_public": true
}
]
}- 401 — Unauthorized
GET /files/:id
Replace :id with the file's file_id.
Code example
bash
curl -X GET "https://api.atiru.io/files/abc123" \
-H "Authorization: Bearer YOUR_API_KEY"javascript
const res = await fetch('https://api.atiru.io/files/abc123', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
})
const file = await res.json()python
import requests
res = requests.get(
'https://api.atiru.io/files/abc123',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
file = res.json()Request
- Path:
:id— File ID (file_id).
Response
- 200 — Success. Single file object (same shape as items in GET /files).
- 401 — Unauthorized
- 404 — File not found
DELETE /files/:id
Code example
bash
curl -X DELETE "https://api.atiru.io/files/abc123" \
-H "Authorization: Bearer YOUR_API_KEY"javascript
await fetch('https://api.atiru.io/files/abc123', {
method: 'DELETE',
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
})python
import requests
requests.delete(
'https://api.atiru.io/files/abc123',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)Request
- Path:
:id— File ID (file_id).
Response
- 204 — No body. File deleted.
- 401 — Unauthorized
- 403 — Trial ended
- 404 — File not found
POST /files/bulk-delete
Code example
bash
curl -X POST "https://api.atiru.io/files/bulk-delete" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"ids":["abc123","def456"]}'javascript
const res = await fetch('https://api.atiru.io/files/bulk-delete', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ ids: ['abc123', 'def456'] }),
})
const { deleted, errors } = await res.json()python
import requests
res = requests.post(
'https://api.atiru.io/files/bulk-delete',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
json={'ids': ['abc123', 'def456']},
)
data = res.json()Request
- Body
json
{
"ids": ["abc123", "def456"]
}| Field | Type | Required | Description |
|---|---|---|---|
| ids | string[] | Yes | 1–100 file IDs |
Response
- 200 — Success
json
{
"deleted": 2,
"errors": [
{
"id": "nonexistent",
"error": "File not found"
}
]
}- 400 — Bad request (e.g. empty ids)
- 401 — Unauthorized
Settings
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /settings | Yes | Get user settings |
| PATCH | /settings | Yes | Update settings |
GET /settings
Code example
bash
curl -X GET "https://api.atiru.io/settings" \
-H "Authorization: Bearer YOUR_API_KEY"javascript
const res = await fetch('https://api.atiru.io/settings', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
})
const settings = await res.json()python
import requests
res = requests.get(
'https://api.atiru.io/settings',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
settings = res.json()Request
- No query params or body.
Response
- 200 — Success
json
{
"public_url_base": "https://cdn.example.com",
"max_upload_size_bytes": 52428800
}- 401 — Unauthorized
PATCH /settings
Code example
bash
curl -X PATCH "https://api.atiru.io/settings" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"public_url_base":"https://cdn.example.com","max_upload_size_bytes":20971520}'javascript
const res = await fetch('https://api.atiru.io/settings', {
method: 'PATCH',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
public_url_base: 'https://cdn.example.com',
max_upload_size_bytes: 20971520,
}),
})
const settings = await res.json()python
import requests
res = requests.patch(
'https://api.atiru.io/settings',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
json={
'public_url_base': 'https://cdn.example.com',
'max_upload_size_bytes': 20971520,
},
)
settings = res.json()Request
- Body
json
{
"public_url_base": "https://cdn.example.com",
"max_upload_size_bytes": 20971520
}Both fields optional; send only the ones you want to update.
Response
- 200 — Success. Same shape as GET /settings.
- 400 — Bad request
- 401 — Unauthorized
Usage
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /usage | Yes | Get usage stats |
GET /usage
Code example
bash
curl -X GET "https://api.atiru.io/usage" \
-H "Authorization: Bearer YOUR_API_KEY"javascript
const res = await fetch('https://api.atiru.io/usage', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
})
const usage = await res.json()python
import requests
res = requests.get(
'https://api.atiru.io/usage',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
usage = res.json()Request
- No query params or body.
Response
- 200 — Success
json
{
"storage_bytes": 1048576,
"files_count": 42,
"origin_reads": 150,
"image_ops": 80,
"period_start": "2024-01-01T00:00:00.000Z",
"period_end": "2024-01-31T23:59:59.000Z"
}- 401 — Unauthorized
Logs
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /logs | Yes | Get activity logs |
GET /logs
Code example
bash
curl -X GET "https://api.atiru.io/logs?page=1&limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"javascript
const res = await fetch('https://api.atiru.io/logs?page=1&limit=20', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
})
const { logs, total, page, limit } = await res.json()python
import requests
res = requests.get(
'https://api.atiru.io/logs',
params={'page': 1, 'limit': 20},
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
data = res.json()Request
- Query
| Param | Type | Default | Description |
|---|---|---|---|
| page | number | 1 | Page number |
| limit | number | — | Items per page |
Response
- 200 — Success
json
{
"logs": [
{
"id": "uuid",
"method": "GET",
"path": "/files",
"status_code": 200,
"request_size_bytes": null,
"created_at": "2024-01-15T12:00:00.000Z",
"metadata": {}
}
],
"total": 100,
"page": 1,
"limit": 20
}- 401 — Unauthorized
Profile
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /profile | Yes | Get profile (user + plan) |
GET /profile
Code example
bash
curl -X GET "https://api.atiru.io/profile" \
-H "Authorization: Bearer YOUR_API_KEY"javascript
const res = await fetch('https://api.atiru.io/profile', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
})
const profile = await res.json()python
import requests
res = requests.get(
'https://api.atiru.io/profile',
headers={'Authorization': 'Bearer YOUR_API_KEY'},
)
profile = res.json()Request
- No query params or body.
Response
- 200 — Success. User and plan info, including
subscription_canceled_at,access_untilfor billing display. - 401 — Unauthorized
Reference (no auth)
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /reference/allowed-content-types | No | List allowed MIME types for upload |
| GET | /reference/for-agents | No | Agent discovery payload |
| GET | /reference/openapi.json | No | OpenAPI 3.0 spec |
File schema
File objects returned by the API follow this shape:
json
{
"id": "uuid",
"user_id": "uuid",
"file_id": "string",
"name": "string or null",
"content_type": "string or null",
"size": "number or null",
"public_url": "string or null",
"default_url": "string or null",
"default_download_url": "string or null",
"public_download_url": "string or null",
"created_at": "string or null",
"is_public": "boolean or null"
}