Quickstart
This guide gets you from zero to your first successful API call in under 5 minutes.
Prerequisites
Before you begin, you'll need:
- An API key from cmfy.cloud
- A tool to make HTTP requests (cURL, Postman, or your language's HTTP library)
Step 1: Get Your API Key
- Log in to the cmfy.cloud portal
- Navigate to API Keys in the sidebar
- Click Create New Key
- Copy your key (it starts with
sk_live_orsk_test_)
Store Your Key Securely
Your API key is shown only once. Store it in a secure location like a password manager or environment variable. Never commit it to version control.
Step 2: Submit a Workflow
Here's a minimal text-to-image workflow:
- cURL
- Python
- JavaScript
- Go
curl -X POST https://api.cmfy.cloud/v1/jobs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": {
"1": {
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors"
}
},
"2": {
"class_type": "CLIPTextEncode",
"inputs": {
"text": "a beautiful sunset over mountains, digital art",
"clip": ["1", 1]
}
},
"3": {
"class_type": "CLIPTextEncode",
"inputs": {
"text": "blurry, low quality, watermark",
"clip": ["1", 1]
}
},
"4": {
"class_type": "EmptyLatentImage",
"inputs": {
"width": 1024,
"height": 1024,
"batch_size": 1
}
},
"5": {
"class_type": "KSampler",
"inputs": {
"seed": 42,
"steps": 25,
"cfg": 7.0,
"sampler_name": "euler_ancestral",
"scheduler": "normal",
"denoise": 1.0,
"model": ["1", 0],
"positive": ["2", 0],
"negative": ["3", 0],
"latent_image": ["4", 0]
}
},
"6": {
"class_type": "VAEDecode",
"inputs": {
"samples": ["5", 0],
"vae": ["1", 2]
}
},
"7": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "output",
"images": ["6", 0]
}
}
}
}'
import requests
API_KEY = "YOUR_API_KEY"
workflow = {
"prompt": {
"1": {
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors"
}
},
"2": {
"class_type": "CLIPTextEncode",
"inputs": {
"text": "a beautiful sunset over mountains, digital art",
"clip": ["1", 1]
}
},
"3": {
"class_type": "CLIPTextEncode",
"inputs": {
"text": "blurry, low quality, watermark",
"clip": ["1", 1]
}
},
"4": {
"class_type": "EmptyLatentImage",
"inputs": {
"width": 1024,
"height": 1024,
"batch_size": 1
}
},
"5": {
"class_type": "KSampler",
"inputs": {
"seed": 42,
"steps": 25,
"cfg": 7.0,
"sampler_name": "euler_ancestral",
"scheduler": "normal",
"denoise": 1.0,
"model": ["1", 0],
"positive": ["2", 0],
"negative": ["3", 0],
"latent_image": ["4", 0]
}
},
"6": {
"class_type": "VAEDecode",
"inputs": {
"samples": ["5", 0],
"vae": ["1", 2]
}
},
"7": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "output",
"images": ["6", 0]
}
}
}
}
response = requests.post(
"https://api.cmfy.cloud/v1/jobs",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json=workflow
)
print(response.json())
const API_KEY = 'YOUR_API_KEY';
const workflow = {
prompt: {
'1': {
class_type: 'CheckpointLoaderSimple',
inputs: {
ckpt_name: 'https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors'
}
},
'2': {
class_type: 'CLIPTextEncode',
inputs: {
text: 'a beautiful sunset over mountains, digital art',
clip: ['1', 1]
}
},
'3': {
class_type: 'CLIPTextEncode',
inputs: {
text: 'blurry, low quality, watermark',
clip: ['1', 1]
}
},
'4': {
class_type: 'EmptyLatentImage',
inputs: {
width: 1024,
height: 1024,
batch_size: 1
}
},
'5': {
class_type: 'KSampler',
inputs: {
seed: 42,
steps: 25,
cfg: 7.0,
sampler_name: 'euler_ancestral',
scheduler: 'normal',
denoise: 1.0,
model: ['1', 0],
positive: ['2', 0],
negative: ['3', 0],
latent_image: ['4', 0]
}
},
'6': {
class_type: 'VAEDecode',
inputs: {
samples: ['5', 0],
vae: ['1', 2]
}
},
'7': {
class_type: 'SaveImage',
inputs: {
filename_prefix: 'output',
images: ['6', 0]
}
}
}
};
const response = await fetch('https://api.cmfy.cloud/v1/jobs', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(workflow)
});
const data = await response.json();
console.log(data);
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
apiKey := "YOUR_API_KEY"
workflow := map[string]interface{}{
"prompt": map[string]interface{}{
"1": map[string]interface{}{
"class_type": "CheckpointLoaderSimple",
"inputs": map[string]interface{}{
"ckpt_name": "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors",
},
},
"2": map[string]interface{}{
"class_type": "CLIPTextEncode",
"inputs": map[string]interface{}{
"text": "a beautiful sunset over mountains, digital art",
"clip": []interface{}{"1", 1},
},
},
"3": map[string]interface{}{
"class_type": "CLIPTextEncode",
"inputs": map[string]interface{}{
"text": "blurry, low quality, watermark",
"clip": []interface{}{"1", 1},
},
},
"4": map[string]interface{}{
"class_type": "EmptyLatentImage",
"inputs": map[string]interface{}{
"width": 1024,
"height": 1024,
"batch_size": 1,
},
},
"5": map[string]interface{}{
"class_type": "KSampler",
"inputs": map[string]interface{}{
"seed": 42,
"steps": 25,
"cfg": 7.0,
"sampler_name": "euler_ancestral",
"scheduler": "normal",
"denoise": 1.0,
"model": []interface{}{"1", 0},
"positive": []interface{}{"2", 0},
"negative": []interface{}{"3", 0},
"latent_image": []interface{}{"4", 0},
},
},
"6": map[string]interface{}{
"class_type": "VAEDecode",
"inputs": map[string]interface{}{
"samples": []interface{}{"5", 0},
"vae": []interface{}{"1", 2},
},
},
"7": map[string]interface{}{
"class_type": "SaveImage",
"inputs": map[string]interface{}{
"filename_prefix": "output",
"images": []interface{}{"6", 0},
},
},
},
}
body, _ := json.Marshal(workflow)
req, _ := http.NewRequest("POST", "https://api.cmfy.cloud/v1/jobs", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("%+v\n", result)
}
Step 3: Understand the Response
A successful submission returns 202 Accepted:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "queued",
"queue_position": 3,
"estimated_wait_seconds": 45
}
| Field | Description |
|---|---|
job_id | Unique identifier for your job |
status | Current state: queued, running, completed, or failed |
queue_position | Your position in the queue |
estimated_wait_seconds | Approximate wait time |
Step 4: Get Your Results
Option A: Poll for Status
Check the job status using the job ID:
- cURL
- Python
- JavaScript
- Go
curl https://api.cmfy.cloud/v1/jobs/YOUR_JOB_ID \
-H "Authorization: Bearer YOUR_API_KEY"
import requests
job_id = "YOUR_JOB_ID"
API_KEY = "YOUR_API_KEY"
response = requests.get(
f"https://api.cmfy.cloud/v1/jobs/{job_id}",
headers={"Authorization": f"Bearer {API_KEY}"}
)
print(response.json())
const jobId = 'YOUR_JOB_ID';
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(`https://api.cmfy.cloud/v1/jobs/${jobId}`, {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
const data = await response.json();
console.log(data);
package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
jobID := "YOUR_JOB_ID"
apiKey := "YOUR_API_KEY"
req, _ := http.NewRequest("GET", "https://api.cmfy.cloud/v1/jobs/"+jobID, nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("%+v\n", result)
}
When complete:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"created_at": "2024-01-15T10:30:00Z",
"started_at": "2024-01-15T10:30:05Z",
"completed_at": "2024-01-15T10:30:20Z",
"execution_time_ms": 12450,
"outputs": {
"images": ["https://cdn.cmfy.cloud/outputs/image_0.png"]
}
}
Option B: Use Webhooks (Recommended)
Instead of polling, add a webhook_url to receive results automatically:
- cURL
- Python
- JavaScript
- Go
curl -X POST https://api.cmfy.cloud/v1/jobs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": { ... },
"webhook_url": "https://your-server.com/webhook"
}'
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://api.cmfy.cloud/v1/jobs",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"prompt": { ... },
"webhook_url": "https://your-server.com/webhook"
}
)
print(response.json())
const API_KEY = 'YOUR_API_KEY';
const response = await fetch('https://api.cmfy.cloud/v1/jobs', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: { ... },
webhook_url: 'https://your-server.com/webhook'
})
});
const data = await response.json();
console.log(data);
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
apiKey := "YOUR_API_KEY"
payload := map[string]interface{}{
"prompt": map[string]interface{}{ /* ... */ },
"webhook_url": "https://your-server.com/webhook",
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.cmfy.cloud/v1/jobs", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Printf("%+v\n", result)
}
Your endpoint will receive a POST with the completed job data.
Common Errors
| Error | Cause | Solution |
|---|---|---|
401 Unauthorized | Invalid or missing API key | Check your Authorization header |
400 Bad Request | Malformed workflow | Validate your JSON and node structure |
429 Too Many Requests | Rate limit exceeded | Wait and retry, or upgrade your plan |
What's Next?
You've submitted your first job! Here's what to explore next:
- Authentication - API key management and security best practices
- First Workflow - Understanding the workflow format in depth
- Concepts - Learn how cmfy.cloud works under the hood
Was this page helpful?