Docs
Dashboard Home Sign In

Overview

SyncNode is a unified AI API gateway. Run AI tasks across multiple providers through a single endpoint — no separate integrations needed. Connect your provider keys once, and SyncNode handles routing, billing, file hosting, and result tracking.

Content Moderation

Moderate text & images in one call. Get safety scores instantly.

Chat Completions

GPT, Claude, Llama & 200+ models via OpenRouter or direct OpenAI.

Image Generation

Generate images & video with any Replicate model + auto CDN hosting.

Face Swap

Swap faces in images with a single API call.

Simple Billing

Pay-as-you-go. Auto-recharge when balance is low.

Auto File Hosting

Generated files auto-upload to your Bunny CDN or S3 bucket.

Base URLs

ServiceBase URL
AI Tasks (Chat, Images, Face Swap)https://run.syncnode.ai
Content Moderationhttps://moderate.syncnode.ai

Quickstart

Get up and running in under 2 minutes.

  1. Create an accountSign up to get your UID and a $5.00 starting balance.
  2. Add your provider API keys — Go to API Keys and add your OpenRouter, OpenAI, Replicate, or Hugging Face key.
  3. Make your first API call — Use the examples in the endpoint pages or the API Playground.
  4. Check results — View task status and output on your Dashboard or poll the status endpoint.
Tip: The Moderation endpoint works out of the box — no provider keys needed. Try it first!

Authentication

All API requests require your UID (User ID). Some endpoints also require a Bearer token (your Supabase JWT). Your UID is on your API Keys page.

Authenticated Request

Include both uid in the body/query and a Bearer token in the header for protected endpoints.

cURL
curl -X POST https://run.syncnode.ai/chat-completion \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -d '{"uid": "__UID__"}'

Public Endpoints (UID only)

These only need your uid — no Bearer token:

  • POST /chat-completion
  • POST /chatgpt-completion
  • POST /generate
  • POST /face-swap/run
  • GET /prediction-status
  • GET /balance
  • POST https://moderate.syncnode.ai

Pricing

Simple, per-call pricing. No subscriptions.

EndpointCost per Call
Chat Completion (OpenRouter)$0.02
ChatGPT Completion (OpenAI)$0.02
Image / Video Generation (Replicate)$0.02
Face Swap$0.02
Content Moderation$0.01

New accounts start with $5.00 free credits. Auto-recharge triggers when your balance drops below $0.01 (configurable threshold, default $50).

Content Moderation

Moderate text and images in a single request. Returns granular safety scores for harassment, hate, violence, sexual content, self-harm, and more — plus a simple safe flag. No provider API keys needed.

POST https://moderate.syncnode.ai $0.01 / call

Request Parameters

ParameterTypeRequiredDescription
uidstringrequiredYour user ID
textstringoptionalText content to moderate
imageUrlstringoptionalURL of image to moderate
imageBase64stringoptionalBase64-encoded image data
imageMimestringoptionalMIME type when using imageBase64 (e.g. image/png)
At least one of text, imageUrl, or imageBase64 must be provided. You can combine text + image in a single call.

Text + Image Moderation

cURL
curl -X POST "https://moderate.syncnode.ai" \
  -H "Content-Type: application/json" \
  -d '{
  "uid": "__UID__",
  "text": "Hello, this is a test message",
  "imageUrl": "https://example.com/photo.jpg"
}'
JavaScript
const response = await fetch("https://moderate.syncnode.ai", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    uid: "__UID__",
    text: "Hello, this is a test message",
    imageUrl: "https://example.com/photo.jpg"
  })
});

const result = await response.json();
console.log(result.overall_moderation.safe); // 1 = safe, 0 = flagged
Python
import requests

response = requests.post("https://moderate.syncnode.ai", json={
    "uid": "__UID__",
    "text": "Hello, this is a test message",
    "imageUrl": "https://example.com/photo.jpg"
})

result = response.json()
print(result["overall_moderation"]["safe"])  # 1 = safe, 0 = flagged

Response

JSON Response
{
  "uid": "__UID__",
  "text_moderation": {
    "scores": {
      "harassment": 0.00004,
      "harassment/threatening": 0.000007,
      "sexual": 0.003,
      "hate": 0.00001,
      "hate/threatening": 0.0000005,
      "illicit": 0.00001,
      "illicit/violent": 0.000009,
      "self-harm/intent": 0.000002,
      "self-harm/instructions": 0.000001,
      "self-harm": 0.000006,
      "sexual/minors": 0.00002,
      "violence": 0.0005,
      "violence/graphic": 0.000009
    },
    "nudity": 0, "underage": 0, "vulgar": 0, "safe": 1
  },
  "image_moderation": {
    "scores": { "harassment": 0, "sexual": 0.00007, "violence": 0.023, "self-harm": 0.004 },
    "nudity": 0, "underage": 0, "vulgar": 0, "safe": 1
  },
  "overall_moderation": { "nudity": 0, "underage": 0, "vulgar": 0, "safe": 1 }
}

Response Fields

FieldDescription
text_moderationPresent when text was provided. Contains per-category scores and flags.
image_moderationPresent when an image was provided. Contains per-category scores and flags.
overall_moderationCombined result across all inputs.
safe1 = content is safe, 0 = content was flagged.
nudity / underage / vulgar0 or 1 — specific content flags.
scoresGranular 0–1 scores for each moderation category (lower = safer).

Text Only

cURL
curl -X POST "https://moderate.syncnode.ai" \
  -H "Content-Type: application/json" \
  -d '{"uid": "__UID__", "text": "Check if this text is safe"}'

Image Only (URL)

cURL
curl -X POST "https://moderate.syncnode.ai" \
  -H "Content-Type: application/json" \
  -d '{"uid": "__UID__", "imageUrl": "https://example.com/image.jpg"}'

Image Only (Base64)

cURL
curl -X POST "https://moderate.syncnode.ai" \
  -H "Content-Type: application/json" \
  -d '{
  "uid": "__UID__",
  "imageBase64": "iVBORw0KGgoAAAANS...",
  "imageMime": "image/png"
}'
Best Practice: Always check overall_moderation.safe first. If 0, inspect scores to see which categories were flagged.

Chat Completion (OpenRouter)

Send chat messages to 200+ AI models via OpenRouter. Requires an OpenRouter API key in your API Keys settings.

POST https://run.syncnode.ai/chat-completion $0.02 / call

Request Parameters

ParameterTypeRequiredDescription
uidstringrequiredYour user ID
modelstringrequiredModel ID (e.g. openai/gpt-4o, anthropic/claude-3.5-sonnet)
messagesarrayrequiredArray of {role, content} message objects
promptstringoptionalAlternative to messages for simple single prompts
max_tokensnumberoptionalMaximum tokens in response
temperaturenumberoptionalSampling temperature (0–2)
cURL
curl -X POST https://run.syncnode.ai/chat-completion \
  -H "Content-Type: application/json" \
  -d '{
  "uid": "__UID__",
  "model": "openai/gpt-4o",
  "messages": [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "Explain quantum computing in 3 sentences."}
  ],
  "max_tokens": 500,
  "temperature": 0.7
}'
JavaScript
const response = await fetch("https://run.syncnode.ai/chat-completion", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    uid: "__UID__",
    model: "openai/gpt-4o",
    messages: [
      { role: "system", content: "You are a helpful assistant." },
      { role: "user", content: "Explain quantum computing in 3 sentences." }
    ],
    max_tokens: 500,
    temperature: 0.7
  })
});
const data = await response.json();
console.log(data.prediction.output.choices[0].message.content);
Python
import requests

response = requests.post("https://run.syncnode.ai/chat-completion", json={
    "uid": "__UID__",
    "model": "openai/gpt-4o",
    "messages": [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain quantum computing in 3 sentences."}
    ],
    "max_tokens": 500,
    "temperature": 0.7
})
data = response.json()
print(data["prediction"]["output"]["choices"][0]["message"]["content"])

Response

JSON Response
{
  "prediction": {
    "id": 123,
    "uid": "__UID__",
    "output": {
      "model": "openai/gpt-4o",
      "choices": [{
        "index": 0,
        "message": { "role": "assistant", "content": "Quantum computing uses qubits..." },
        "finish_reason": "stop"
      }],
      "usage": { "prompt_tokens": 25, "completion_tokens": 85, "total_tokens": 110 }
    },
    "cost": 0.02, "model": "openai/gpt-4o", "status": "completed",
    "job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

ChatGPT Completion (Direct OpenAI)

Send requests directly to the OpenAI API. Requires an OpenAI API key stored in your API Keys.

POST https://run.syncnode.ai/chatgpt-completion $0.02 / call
cURL
curl -X POST https://run.syncnode.ai/chatgpt-completion \
  -H "Content-Type: application/json" \
  -d '{
  "uid": "__UID__",
  "model": "gpt-4o",
  "messages": [
    {"role": "user", "content": "Write a haiku about programming."}
  ],
  "max_tokens": 100,
  "temperature": 0.8
}'
Difference: /chat-completion routes through OpenRouter (200+ models). /chatgpt-completion goes directly to OpenAI using your OpenAI key.

Image & Video Generation

Generate images, videos, and audio using any Replicate model. Results auto-upload to your configured CDN host. Requires a Replicate API key.

POST https://run.syncnode.ai/generate $0.02 / call

Request Parameters

ParameterTypeRequiredDescription
uidstringrequiredYour user ID
modelstringrequiredReplicate model ID (e.g. stability-ai/sdxl or full version hash)
inputobjectrequiredModel-specific input parameters

Generate an Image

cURL
curl -X POST https://run.syncnode.ai/generate \
  -H "Content-Type: application/json" \
  -d '{
  "uid": "__UID__",
  "model": "adirik/realvisxl-v3.0-turbo:3dc73c80...",
  "input": {
    "width": 768, "height": 768,
    "prompt": "A serene mountain landscape at sunset, photorealistic",
    "negative_prompt": "low quality, blurry, sketch",
    "num_outputs": 1, "guidance_scale": 7, "num_inference_steps": 25
  }
}'

Generate a Video

cURL
curl -X POST https://run.syncnode.ai/generate \
  -H "Content-Type: application/json" \
  -d '{
  "uid": "__UID__",
  "model": "bytedance/seedance-1-lite",
  "input": {
    "fps": 24, "prompt": "A woman walks through a sunlit park",
    "duration": 5, "resolution": "720p", "aspect_ratio": "16:9"
  }
}'

Response (Job Created)

JSON
{
  "success": true,
  "job_id": "b6nqrw6zbdrmc0cqwqbr8b3dm8",
  "get": "https://run.syncnode.ai/prediction-status?job_id=b6nqrw6zbdrmc0cqwqbr8b3dm8",
  "status": "in_progress"
}
Image/video generation is async. Use the get URL or the Prediction Status endpoint to poll for results.

Face Swap

Swap faces between two images. Provide source and target as base64-encoded strings.

POST https://run.syncnode.ai/face-swap/run $0.02 / call

Request Parameters

ParameterTypeRequiredDescription
uidstringrequiredYour user ID
input.source_imagestringrequiredBase64 source face image
input.target_imagestringrequiredBase64 target image
input.background_enhancebooleanoptionalEnhance background quality
cURL
curl -X POST https://run.syncnode.ai/face-swap/run \
  -H "Content-Type: application/json" \
  -d '{
  "uid": "__UID__",
  "input": {
    "source_image": "BASE64_SOURCE_FACE...",
    "target_image": "BASE64_TARGET_IMAGE...",
    "background_enhance": true
  }
}'
Face swap is async. Poll /face-swap/status?job_id=... for the result.

Prediction Status

Poll for results of async jobs (image generation, face swap).

GET https://run.syncnode.ai/prediction-status?job_id={job_id}
cURL
curl "https://run.syncnode.ai/prediction-status?job_id=b6nqrw6zbdrmc0cqwqbr8b3dm8"

Response (Completed)

JSON
{
  "job_id": "b6nqrw6zbdrmc0cqwqbr8b3dm8",
  "replicate_status": "completed",
  "output": "https://your-cdn.b-cdn.net/gen_abc123_1752140031948.png",
  "updated": true
}

Status Values

StatusDescription
in_progressJob is still processing
completedDone — output contains the result URL
failedFailed — check error field
Polling: We recommend every 2–5 seconds until status changes from in_progress.

Balance

Check your current credit balance.

GET https://run.syncnode.ai/balance?uid={uid}
cURL
curl "https://run.syncnode.ai/balance?uid=__UID__"
JSON Response
{"balance": 4.96}

API Keys

Manage your provider API keys. Stored securely and used to authenticate to providers on your behalf.

GET https://run.syncnode.ai/api-keys?uid={uid}
JSON Response
{
  "replicate_key": "r8_abc...",
  "chatgpt_key": "sk-abc...",
  "huggingface_key": "hf_abc...",
  "openrouter_key": "sk-or-v1-abc..."
}
POST https://run.syncnode.ai/api-keys
cURL
curl -X POST https://run.syncnode.ai/api-keys \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{"uid": "__UID__", "openrouter_key": "sk-or-v1-your-key-here"}'

Supported Providers

Key NameProviderUsed By
openrouter_keyOpenRouter/chat-completion
chatgpt_keyOpenAI/chatgpt-completion
replicate_keyReplicate/generate
huggingface_keyHugging FaceUsage tracking

Tasks

List, view, and manage your task history.

GET https://run.syncnode.ai/tasks?uid={uid}&page=1&size=10
JSON Response
{
  "tasks": [{
    "id": 1, "job_id": "abc-123", "model": "openai/gpt-4o",
    "prompt": "Explain AI", "status": "completed", "cost": 0.02,
    "created_at": "2025-07-08T10:00:00Z"
  }],
  "page": 1, "size": 10, "total": 42
}
GET https://run.syncnode.ai/tasks/{id}?uid={uid} View single task
DELETE https://run.syncnode.ai/tasks/{id} Delete a task

Billing

View billing history, set auto-recharge thresholds, and manage payment methods.

EndpointMethodDescription
/billing-history?uid={uid}GETGet charge history
/billing-threshold?uid={uid}GETGet auto-recharge threshold
/billing-thresholdPOSTSet auto-recharge threshold
/card?uid={uid}GETView saved payment card
/topup_cardPOSTTop up balance
Auto-Recharge: When balance drops below $0.01, SyncNode charges your saved card for the threshold amount (default $50). Change this in Billing settings.

API Playground

Test endpoints directly from this page. Your UID is auto-filled when signed in.

Error Codes

Standard HTTP error codes returned by the API.

CodeMeaning
200Success
400Bad request — missing or invalid parameters
401Unauthorized — invalid or missing token
402Payment required — insufficient balance, no card on file
404Not found
500Server error

Error Response Format

JSON
{"error": "Missing uid parameter"}