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 API key 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 SyncNode API key (sent as apiKey in the request body or query string). Some endpoints also require a Bearer token for additional authentication. Both are on your API Key page.

Field naming: SyncNode accepts the API key under any of three field names — apiKey (preferred, modern), api_key (snake_case alternative), or uid (legacy alias). Pick whichever fits your codebase; they all behave identically. These docs use apiKey for examples.

Authenticated Request

Include both apiKey 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 '{"apiKey": "__API_KEY__"}'

Public Endpoints (API key only)

These only need your API key (sent as apiKey) — 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.005

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.005 / call

Request Parameters

ParameterTypeRequiredDescription
apiKeystringrequiredYour SyncNode API key (from /api_keys)
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 '{
  "apiKey": "__API_KEY__",
  "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({
    apiKey: "__API_KEY__",
    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={
    "apiKey": "__API_KEY__",
    "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
{
  "apiKey": "__API_KEY__",
  "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 '{"apiKey": "__API_KEY__", "text": "Check if this text is safe"}'

Image Only (URL)

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

Image Only (Base64)

cURL
curl -X POST "https://moderate.syncnode.ai" \
  -H "Content-Type: application/json" \
  -d '{
  "apiKey": "__API_KEY__",
  "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
apiKeystringrequiredYour SyncNode API key (from /api_keys)
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 '{
  "apiKey": "__API_KEY__",
  "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({
    apiKey: "__API_KEY__",
    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={
    "apiKey": "__API_KEY__",
    "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,
    "apiKey": "__API_KEY__",
    "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 '{
  "apiKey": "__API_KEY__",
  "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 & Audio Generation via Replicate

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

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

Request Parameters

ParameterTypeRequiredDescription
apiKeystringrequiredYour SyncNode API key (from /api_keys)
modelstringrequiredReplicate model ID (e.g. stability-ai/sdxl or full version hash)
inputobjectrequiredModel-specific input parameters

Generate an Image (Flux Schnell — fast)

cURL
curl -X POST https://run.syncnode.ai/generate \
  -H "Content-Type: application/json" \
  -d '{
  "apiKey": "__API_KEY__",
  "model": "black-forest-labs/flux-schnell",
  "input": {
    "prompt": "A serene mountain landscape at sunset, photorealistic",
    "aspect_ratio": "16:9",
    "num_outputs": 1,
    "output_format": "webp"
  }
}'

Generate an Image (RealVisXL — higher quality)

cURL
curl -X POST https://run.syncnode.ai/generate \
  -H "Content-Type: application/json" \
  -d '{
  "apiKey": "__API_KEY__",
  "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 '{
  "apiKey": "__API_KEY__",
  "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.

Image, Video & Audio Generation via FAL

Run any model from fal.ai through SyncNode — images, video, audio, multimodal. Submission is queued and SyncNode polls FAL until the job completes, then uploads the result to your CDN. Requires a FAL API key saved under Provider Credentials.

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

Request Parameters

ParameterTypeRequiredDescription
apiKeystringrequiredYour SyncNode API key (from /api_keys)
modelstringrequiredFull FAL model path (e.g. fal-ai/recraft/v4.1/text-to-image, fal-ai/flux/dev). The model is part of the URL on FAL's side.
inputobjectrequiredModel-specific input (e.g. prompt, image_size, enable_safety_checker). Forwarded directly to FAL.

Generate an Image

cURL
curl -X POST https://run.syncnode.ai/fal/generate \
  -H "Content-Type: application/json" \
  -d '{
  "apiKey": "__API_KEY__",
  "model": "fal-ai/recraft/v4.1/text-to-image",
  "input": {
    "prompt": "Tilt-shift miniature of a Portuguese fishing village at golden hour",
    "image_size": "landscape_16_9",
    "enable_safety_checker": true
  }
}'

Response (Job Created)

JSON
{
  "success": true,
  "job_id": "eff9450f-84e5-4aeb-86e8-3ec1a197c033",
  "provider_job_id": "019e314d-ed5f-70d1-8781-20ac1eb39f06",
  "task_status": "IN_QUEUE",
  "status": "in_progress"
}

Poll Status

GET https://run.syncnode.ai/fal/status?job_id={job_id}
cURL
curl "https://run.syncnode.ai/fal/status?job_id=eff9450f-84e5-4aeb-86e8-3ec1a197c033"

Task Status Values

StatusDescription
IN_QUEUESubmitted, waiting to start
IN_PROGRESSModel is running
COMPLETEDDone — output contains the final URL (uploaded to your CDN host if configured)
FAILEDFailed — check output for the error message
SyncNode also polls FAL every 60 seconds via a background cron, so completion happens even if you never call /fal/status. Manual polling just makes it faster.

Image, Video & Audio Generation via Alibaba DashScope

Run Wan family models (image, video, multimodal) from Alibaba DashScope through SyncNode. Image and multimodal generation can be synchronous; video generation is always async. Requires an Alibaba DashScope API key saved under Provider Credentials.

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

Request Parameters

ParameterTypeRequiredDescription
apiKeystringrequiredYour SyncNode API key (from /api_keys)
modelstringrequiredDashScope model name (e.g. wan2.7-image-pro, wan2.7-i2v)
inputobjectrequiredDashScope input. For multimodal: { messages: [...] }. For video: { prompt, media: [...] }.
parametersobjectoptionalModel-specific knobs: size, resolution, duration, n, watermark, prompt_extend, etc.
endpointstringoptionalOverride the DashScope endpoint path. Defaults are inferred from model name.

Generate an Image (Wan Image Pro)

cURL
curl -X POST https://run.syncnode.ai/alibaba/generate \
  -H "Content-Type: application/json" \
  -d '{
  "apiKey": "__API_KEY__",
  "model": "wan2.7-image-pro",
  "input": {
    "messages": [{
      "role": "user",
      "content": [{ "text": "A futuristic cyberpunk city at night, neon lights, rain" }]
    }]
  },
  "parameters": { "size": "2K", "n": 1, "watermark": false }
}'

Generate a Video (Wan i2v)

cURL
curl -X POST https://run.syncnode.ai/alibaba/generate \
  -H "Content-Type: application/json" \
  -d '{
  "apiKey": "__API_KEY__",
  "model": "wan2.7-i2v",
  "input": {
    "prompt": "A cat surfing on a wave",
    "media": [
      { "type": "first_frame", "url": "https://example.com/first.jpg" }
    ]
  },
  "parameters": { "resolution": "1080P", "duration": 5, "prompt_extend": true }
}'

Response (Async Job)

JSON
{
  "success": true,
  "job_id": "a3c8...",
  "provider_job_id": "ds-task-abc...",
  "task_status": "PENDING",
  "status": "in_progress"
}

Poll Status

GET https://run.syncnode.ai/alibaba/status?job_id={job_id}
cURL
curl "https://run.syncnode.ai/alibaba/status?job_id=a3c8..."

Task Status Values

StatusDescription
PENDING / QUEUEDSubmitted, waiting to start
RUNNINGModel is running
SUCCEEDEDDone — output contains the final URL (uploaded to your CDN host if configured)
FAILED / CANCELEDFailed — check output for the error message
Video models on DashScope can take several minutes. SyncNode polls every 60 seconds in the background, so the prediction row finalizes automatically even without manual polling.
Video input quirk: For i2v models, SyncNode automatically re-uploads your image URLs to DashScope OSS first (DashScope's backend can't reliably fetch external CDN URLs). You don't need to do anything — just pass an https://... URL.

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
apiKeystringrequiredYour SyncNode API key (from /api_keys)
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 '{
  "apiKey": "__API_KEY__",
  "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?apiKey={apiKey}
cURL
curl "https://run.syncnode.ai/balance?apiKey=__API_KEY__"
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?apiKey={apiKey}
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 '{"apiKey": "__API_KEY__", "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?apiKey={apiKey}&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}?apiKey={apiKey} 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?apiKey={apiKey}GETGet charge history
/billing-threshold?apiKey={apiKey}GETGet auto-recharge threshold
/billing-thresholdPOSTSet auto-recharge threshold
/card?apiKey={apiKey}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 API key is auto-filled when signed in.

Claude Code Skill

Use SyncNode from inside Claude Code with a single install. The official SyncNode skill teaches Claude every endpoint, the auth flow, polling lifecycle, and pricing — so you can scaffold integrations by describing what you want instead of reading docs.

What it does

When you ask Claude Code something like "add image generation to my app via SyncNode" or "use SyncNode to wire up chat completions", the skill loads automatically and gives Claude:

  • The full endpoint surface (/generate, /chat-completion, /fal/generate, /alibaba/generate, /face-swap/run, /moderate)
  • Auth pattern (API key + Bearer JWT)
  • Polling lifecycle for async jobs
  • Cost-per-call so it can warn before burning your balance
  • Working code samples in cURL, JavaScript, and Python
  • Common errors and how to fix them

Install

Option 1 — Global (recommended)

Clone into your user-level skills directory and it's available in every project:

bash
git clone https://github.com/syncnode-ai/claude-skill.git ~/.claude/skills/syncnode

Restart Claude Code. The skill auto-loads when its trigger description matches your prompt.

Option 2 — Per-project

Drop the SKILL.md (and examples/) into .claude/skills/syncnode/ inside your project. Anyone using Claude Code in that repo gets it.

Verify it's loaded

In Claude Code, type /skillssyncnode should appear in the list. Then try:

prompt
Set me up to use SyncNode for image generation

Claude should walk you through getting an API key, adding a Replicate provider credential, and scaffolding a working /generate call.

Repository

Source, examples, and contribution guidelines live on GitHub:

github.com/syncnode-ai/claude-skill

Direct link to the skill definition: SKILL.md

Tip: The skill includes a waitForCompletion() helper in both the JS and Python clients so you don't have to write polling loops for async jobs.

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 API key"}