Jobs
Every API call to cloudlayer.io creates a job. Jobs track the status, parameters, processing time, and cost of each generation request. Use the Jobs API to monitor async requests, debug failed generations, and audit API usage.
Endpoints
GET /v1/jobs/:id
GET /v1/jobs
GET /v2/jobs/:id
GET /v2/jobs
Get a Single Job
Retrieve a specific job by its ID.
GET /v1/jobs/:id
GET /v2/jobs/:id
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The unique job ID. |
Examples
cURL
curl -X GET "https://api.cloudlayer.io/v2/jobs/job_abc123def456" \
-H "X-API-Key: your-api-key-here"
JavaScript (fetch)
const jobId = "job_abc123def456";
const response = await fetch(
`https://api.cloudlayer.io/v2/jobs/${jobId}`,
{
headers: {
"X-API-Key": "your-api-key-here",
},
}
);
const job = await response.json();
console.log(job);
Python (requests)
import requests
job_id = "job_abc123def456"
response = requests.get(
f"https://api.cloudlayer.io/v2/jobs/{job_id}",
headers={"X-API-Key": "your-api-key-here"},
)
job = response.json()
print(job)
Response
{
"id": "job_abc123def456",
"uid": "usr_xyz789",
"apiKeyUsed": "key_...last4",
"type": "html/pdf",
"status": "completed",
"params": {
"format": "letter",
"margin": {
"top": "1in",
"bottom": "1in"
},
"printBackground": true
},
"size": 245760,
"processTime": 2340,
"apiCreditCost": 1,
"worker": "worker-us-east-1a",
"timestamp": "2024-01-15T10:30:00.000Z"
}
List Jobs
Retrieve a paginated list of all jobs, ordered by creation date (newest first).
GET /v1/jobs
GET /v2/jobs
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 25 | Number of jobs to return (max 100). |
offset | number | 0 | Number of jobs to skip for pagination. |
Examples
cURL
# Get the 25 most recent jobs
curl -X GET "https://api.cloudlayer.io/v2/jobs" \
-H "X-API-Key: your-api-key-here"
# Paginate: get jobs 11-20
curl -X GET "https://api.cloudlayer.io/v2/jobs?limit=10&offset=10" \
-H "X-API-Key: your-api-key-here"
JavaScript (fetch)
const response = await fetch(
"https://api.cloudlayer.io/v2/jobs?limit=10",
{
headers: {
"X-API-Key": "your-api-key-here",
},
}
);
const jobs = await response.json();
for (const job of jobs) {
console.log(`${job.id} | ${job.type} | ${job.status} | ${job.processTime}ms`);
}
Python (requests)
import requests
response = requests.get(
"https://api.cloudlayer.io/v2/jobs",
params={"limit": 10},
headers={"X-API-Key": "your-api-key-here"},
)
jobs = response.json()
for job in jobs:
print(f"{job['id']} | {job['type']} | {job['status']} | {job['processTime']}ms")
Response
[
{
"id": "job_abc123def456",
"uid": "usr_xyz789",
"apiKeyUsed": "key_...last4",
"type": "html/pdf",
"status": "completed",
"params": {
"format": "letter",
"printBackground": true
},
"size": 245760,
"processTime": 2340,
"apiCreditCost": 1,
"worker": "worker-us-east-1a",
"timestamp": "2024-01-15T10:30:00.000Z"
},
{
"id": "job_ghi789jkl012",
"uid": "usr_xyz789",
"apiKeyUsed": "key_...last4",
"type": "url/image",
"status": "completed",
"params": {
"url": "https://example.com",
"imageType": "png"
},
"size": 102400,
"processTime": 3150,
"apiCreditCost": 1,
"worker": "worker-us-east-1b",
"timestamp": "2024-01-15T10:25:00.000Z"
}
]
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique job identifier (e.g., "job_abc123def456"). |
uid | string | The user ID that owns this job. |
apiKeyUsed | string | A masked version of the API key used to create this job (last 4 characters visible). Useful for auditing which key was used in multi-key setups. |
type | string | The job type, matching the API endpoint used. See Job Types below. |
status | string | Current job status. See Job Statuses below. |
params | object | The parameters that were sent with the API request (excluding the html or template body for privacy). Useful for debugging and understanding what configuration produced a given result. |
size | number | Size of the generated output file in bytes. 0 for pending or failed jobs. |
processTime | number | Time in milliseconds from when the job started processing to completion. 0 for pending jobs. |
apiCreditCost | number | Number of API credits consumed by this job. |
worker | string | Identifier of the worker instance that processed this job. Useful for support and debugging. |
timestamp | string | ISO 8601 timestamp of when the job was created. |
Job Types
| Type | Description |
|---|---|
html/pdf | HTML to PDF generation |
url/pdf | URL to PDF generation |
template/pdf | Template to PDF generation |
html/image | HTML to image generation |
url/image | URL to image generation |
template/image | Template to image generation |
Job Statuses
| Status | Description |
|---|---|
pending | The job has been created and is waiting to be picked up by a worker. |
processing | The job is currently being processed by a worker. |
completed | The job finished successfully. The generated asset is available for download. |
failed | The job failed. Check the response for error details. |
Polling for Async Jobs
When using async mode, poll the job endpoint to check when processing is complete:
JavaScript (fetch)
async function waitForJob(jobId, apiKey, maxWaitMs = 60000) {
const startTime = Date.now();
const pollInterval = 1000; // 1 second
while (Date.now() - startTime < maxWaitMs) {
const response = await fetch(
`https://api.cloudlayer.io/v2/jobs/${jobId}`,
{ headers: { "X-API-Key": apiKey } }
);
const job = await response.json();
if (job.status === "completed") {
return job;
}
if (job.status === "failed") {
throw new Error(`Job ${jobId} failed`);
}
// Wait before polling again
await new Promise((resolve) => setTimeout(resolve, pollInterval));
}
throw new Error(`Job ${jobId} timed out after ${maxWaitMs}ms`);
}
// Usage
const job = await waitForJob("job_abc123def456", "your-api-key-here");
console.log(`Completed in ${job.processTime}ms, size: ${job.size} bytes`);
Python (requests)
import time
import requests
def wait_for_job(job_id, api_key, max_wait_seconds=60):
start_time = time.time()
poll_interval = 1 # seconds
while time.time() - start_time < max_wait_seconds:
response = requests.get(
f"https://api.cloudlayer.io/v2/jobs/{job_id}",
headers={"X-API-Key": api_key},
)
job = response.json()
if job["status"] == "completed":
return job
if job["status"] == "failed":
raise Exception(f"Job {job_id} failed")
time.sleep(poll_interval)
raise TimeoutError(f"Job {job_id} timed out after {max_wait_seconds}s")
# Usage
job = wait_for_job("job_abc123def456", "your-api-key-here")
print(f"Completed in {job['processTime']}ms, size: {job['size']} bytes")
Usage Analytics
Use the Jobs API to build your own usage dashboards and analytics:
import requests
response = requests.get(
"https://api.cloudlayer.io/v2/jobs",
params={"limit": 100},
headers={"X-API-Key": "your-api-key-here"},
)
jobs = response.json()
# Compute statistics
total_credits = sum(job["apiCreditCost"] for job in jobs)
avg_process_time = sum(job["processTime"] for job in jobs) / len(jobs)
total_bytes = sum(job["size"] for job in jobs)
failed_count = sum(1 for job in jobs if job["status"] == "failed")
print(f"Total credits used: {total_credits}")
print(f"Average processing time: {avg_process_time:.0f}ms")
print(f"Total output size: {total_bytes / 1048576:.2f} MB")
print(f"Failed jobs: {failed_count}")
Tips
- Debugging failures: When a job fails, check the
paramsfield to see what configuration was used. Common issues include timeouts (increase thetimeoutparameter), unreachable URLs, and malformed HTML. - API key auditing: The
apiKeyUsedfield shows which API key was used for each job. Use this to audit usage across multiple keys or team members. - Process time optimization: Monitor
processTimeacross jobs to identify slow generation patterns. Consider reducing viewport size, usingwaitUntil: "domcontentloaded", or simplifying your HTML content. - Pagination: The list endpoint returns a maximum of 100 items per request. Use
limitandoffsetto page through your complete job history.