API Documentation
N1FILTER AI API allows you to generate AI-powered images and videos programmatically. Send an image, choose a preset, and get the result via a simple REST API.
Quick start:
- Create an account and get your API key from the cabinet
- Add the key to
Authorization: Bearer YOUR_API_KEYheader - Call
GET /api/v1/generation/pricesto see available presets - Send a generation request and poll for the result
Authentication
All API requests require an API key passed in the Authorization header as a Bearer token.
Authorization: Bearer sk-abc123def456-7890abcdef123456You can create and manage API keys in your cabinet. Each account can have one active key at a time.
Don't have an API key yet?
Create Free AccountBase URL
https://n1-filter.digital/api/v1Errors
The API returns standard HTTP status codes. Error responses include a JSON body with a detail field.
| Code | Meaning |
|---|---|
400 | Bad request — invalid parameters, unsupported image format, file too large |
401 | Unauthorized — missing or invalid API key |
402 | Insufficient balance — not enough tokens for this generation |
404 | Not found — order doesn't exist or belongs to another user |
410 | Gone — generation result has expired (24h TTL) |
500 | Internal server error |
Error response example:
{
"detail": "Unsupported image type: image/gif. Allowed: jpg, png, webp"
}
/generation/balance
Returns the current token balance for the authenticated user.
Response
{
"token_balance": 5000
}
Code Examples
import httpx
API_KEY = "sk-your-api-key"
BASE = "https://n1-filter.digital/api/v1"
resp = httpx.get(
f"{BASE}/generation/balance",
headers={"Authorization": f"Bearer {API_KEY}"},
)
data = resp.json()
print(f"Balance: {data['token_balance']} tokens")/generation/prices
Returns available generation presets and their prices in tokens.
Response
{
"generation": {
"image": {
"presets": [
{ "id": "preset_1", "price": 100 },
{ "id": "preset_2", "price": 150 }
]
},
"video": {
"presets": [
{ "id": "preset_v1", "price": 300 }
],
"seconds_price": 50
}
}
}
Video pricing:
total cost = preset.price + (seconds - 4) * seconds_price.
Base duration is 4 seconds, max is 8.
Code Examples
import httpx
API_KEY = "sk-your-api-key"
BASE = "https://n1-filter.digital/api/v1"
resp = httpx.get(
f"{BASE}/generation/prices",
headers={"Authorization": f"Bearer {API_KEY}"},
)
prices = resp.json()
for preset in prices["generation"]["image"]["presets"]:
print(f"Image preset {preset['id']}: {preset['price']} tokens")/generation/image
Create an image generation. Send an image file and a preset ID. The cost is deducted from your balance immediately.
Request Body (multipart/form-data)
| Field | Type | Required | Description |
|---|---|---|---|
image | file | Yes | JPEG, PNG, or WebP. Max 5 MB. |
preset_id | string | Yes | Preset ID from /generation/prices |
Response
{
"id": 42,
"user_id": 1,
"type": "image",
"preset_id": "preset_1",
"seconds": null,
"status": "pending",
"tokens_spent": 100,
"tokens_refunded": false,
"result": null,
"error_msg": null,
"created_at": 1711440000.0,
"completed_at": null
}
Code Examples
import httpx
API_KEY = "sk-your-api-key"
BASE = "https://n1-filter.digital/api/v1"
with open("photo.jpg", "rb") as f:
resp = httpx.post(
f"{BASE}/generation/image",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"image": ("photo.jpg", f, "image/jpeg")},
data={"preset_id": "preset_1"},
)
order = resp.json()
print(f"Order #{order['id']} — status: {order['status']}")Want to try it yourself?
Try for Free/generation/video
Create a video generation. Same as image, but with an additional seconds parameter (4-8).
Request Body (multipart/form-data)
| Field | Type | Required | Description |
|---|---|---|---|
image | file | Yes | JPEG, PNG, or WebP. Max 5 MB. |
preset_id | string | Yes | Preset ID from /generation/prices |
seconds | integer | No | Video duration: 4-8 seconds. Default: 4. |
Response
{
"id": 43,
"user_id": 1,
"type": "video",
"preset_id": "preset_v1",
"seconds": 6,
"status": "pending",
"tokens_spent": 400,
"tokens_refunded": false,
"result": null,
"error_msg": null,
"created_at": 1711440060.0,
"completed_at": null
}
Code Examples
import httpx
API_KEY = "sk-your-api-key"
BASE = "https://n1-filter.digital/api/v1"
with open("photo.jpg", "rb") as f:
resp = httpx.post(
f"{BASE}/generation/video",
headers={"Authorization": f"Bearer {API_KEY}"},
files={"image": ("photo.jpg", f, "image/jpeg")},
data={"preset_id": "preset_v1", "seconds": "6"},
)
order = resp.json()
print(f"Video order #{order['id']} — {order['seconds']}s")/generation/orders
List your generation orders. Supports pagination.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 50 | Max items to return (1-100) |
offset | integer | 0 | Number of items to skip |
Response
[
{
"id": 42,
"user_id": 1,
"type": "image",
"preset_id": "preset_1",
"seconds": null,
"status": "completed",
"tokens_spent": 100,
"tokens_refunded": false,
"result": "a1b2c3d4.jpg",
"error_msg": null,
"created_at": 1711440000.0,
"completed_at": 1711440120.0
}
]
Code Examples
resp = httpx.get(
f"{BASE}/generation/orders",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"limit": 10, "offset": 0},
)
orders = resp.json()
for order in orders:
print(f"#{order['id']} [{order['status']}] — {order['tokens_spent']} tokens")/generation/orders/{order_id}
Check the status of a specific order. Use this to poll until the generation is complete.
Order Statuses
| Status | Description |
|---|---|
pending | Order created, waiting to be processed |
processing | Generation is in progress |
completed | Done! Result is ready for download |
failed | Generation failed. Check error_msg. Tokens are refunded automatically. |
canceled | Order was canceled. Tokens are refunded. |
Response
{
"id": 42,
"user_id": 1,
"type": "image",
"preset_id": "preset_1",
"seconds": null,
"status": "completed",
"tokens_spent": 100,
"tokens_refunded": false,
"result": "a1b2c3d4.jpg",
"error_msg": null,
"created_at": 1711440000.0,
"completed_at": 1711440120.0
}
Code Examples
import time
order_id = 42
while True:
resp = httpx.get(
f"{BASE}/generation/orders/{order_id}",
headers={"Authorization": f"Bearer {API_KEY}"},
)
order = resp.json()
print(f"Status: {order['status']}")
if order["status"] in ("completed", "failed", "canceled"):
break
time.sleep(3)/generation/orders/{order_id}/download
Download the generated file. Only available for orders with status: "completed".
Results expire after 24 hours.
Response:
Binary file (image/jpeg, image/png, image/webp, video/mp4, video/webm) with
Content-Disposition header.
Code Examples
order_id = 42
resp = httpx.get(
f"{BASE}/generation/orders/{order_id}/download",
headers={"Authorization": f"Bearer {API_KEY}"},
)
if resp.status_code == 200:
filename = f"result_{order_id}.jpg"
with open(filename, "wb") as f:
f.write(resp.content)
print(f"Saved to {filename}")
elif resp.status_code == 410:
print("Result expired (24h TTL)")Full Integration Flow
Complete example: check balance, create a generation, poll for status, and download the result.
import httpx
import time
API_KEY = "sk-your-api-key"
BASE = "https://n1-filter.digital/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}
# 1. Check balance
balance = httpx.get(f"{BASE}/generation/balance", headers=headers).json()
print(f"Balance: {balance['token_balance']} tokens")
# 2. Get available presets
prices = httpx.get(f"{BASE}/generation/prices", headers=headers).json()
preset_id = prices["generation"]["image"]["presets"][0]["id"]
price = prices["generation"]["image"]["presets"][0]["price"]
print(f"Using preset '{preset_id}' — {price} tokens")
if balance["token_balance"] < price:
print("Not enough tokens!")
exit(1)
# 3. Create generation
with open("photo.jpg", "rb") as f:
resp = httpx.post(
f"{BASE}/generation/image",
headers=headers,
files={"image": ("photo.jpg", f, "image/jpeg")},
data={"preset_id": preset_id},
)
order = resp.json()
order_id = order["id"]
print(f"Order #{order_id} created")
# 4. Poll for completion
while True:
status = httpx.get(
f"{BASE}/generation/orders/{order_id}",
headers=headers,
).json()
print(f" Status: {status['status']}")
if status["status"] == "completed":
break
elif status["status"] in ("failed", "canceled"):
print(f" Error: {status.get('error_msg', 'unknown')}")
exit(1)
time.sleep(3)
# 5. Download result
resp = httpx.get(
f"{BASE}/generation/orders/{order_id}/download",
headers=headers,
)
with open(f"result_{order_id}.jpg", "wb") as f:
f.write(resp.content)
print(f"Done! Saved to result_{order_id}.jpg")