N Nexus Docs
API Reference

AI Jobs API

REST API endpoints for dispatching and monitoring AI worker jobs.

Overview

The AI Jobs API lets you programmatically dispatch AI worker jobs, monitor their status, and retrieve their results. All endpoints require the ai-jobs:write scope to dispatch jobs and ai-jobs:read (or any read scope) to query status.

AI jobs are executed asynchronously by the Python FastAPI worker fleet. After dispatch, poll the job status endpoint until the job reaches a terminal state (completed or failed).

Job Types

Job TypeDescriptionTypical Duration
pricing_recalculateRecompute optimal prices for SKUs10–60 seconds
review_sentimentRun NLP sentiment on new reviews30–120 seconds
return_classifyClassify return reasons + detect anomalies20–90 seconds
llm_visibility_scoreQuery LLM assistants for visibility scoring60–300 seconds
competitor_scanFetch competitor prices for SKUs15–60 seconds
listing_optimizeGenerate listing improvement proposals30–120 seconds

Endpoints

Dispatch Job

POST /api/ai-jobs

Required scope: ai-jobs:write

Request Body:

{
  "type": "pricing_recalculate",
  "params": {
    "skus": ["SKU-001", "SKU-002"],
    "marketplace": "amazon_us",
    "apply": false
  },
  "priority": "normal"
}

Priority levels: low, normal, high. High-priority jobs are processed first in the queue.

Response:

{
  "data": {
    "id": "job_01HXK9MZPQ3B8C7D2E5F6G",
    "type": "pricing_recalculate",
    "status": "queued",
    "priority": "normal",
    "params": {
      "skus": ["SKU-001", "SKU-002"],
      "marketplace": "amazon_us",
      "apply": false
    },
    "created_at": "2026-03-12T14:32:01.123Z",
    "estimated_completion_at": "2026-03-12T14:32:31.123Z"
  }
}

Get Job Status

GET /api/ai-jobs/:jobId

Poll this endpoint after dispatching a job to check progress.

Job Statuses:

StatusDescription
queuedJob is waiting in the queue
runningWorker is processing the job
completedJob finished successfully
failedJob failed after all retries
cancelledJob was cancelled before processing

Example Response (completed):

{
  "data": {
    "id": "job_01HXK9MZPQ3B8C7D2E5F6G",
    "type": "pricing_recalculate",
    "status": "completed",
    "started_at": "2026-03-12T14:32:05.000Z",
    "completed_at": "2026-03-12T14:32:32.000Z",
    "duration_seconds": 27,
    "result": {
      "processed_count": 2,
      "updated_count": 1,
      "recommendations": [
        {
          "sku": "SKU-001",
          "current_price": 14.99,
          "recommended_price": 13.49,
          "confidence": 0.87,
          "applied": false
        },
        {
          "sku": "SKU-002",
          "current_price": 8.99,
          "recommended_price": 8.99,
          "confidence": 0.92,
          "reasoning": "Current price is already optimal",
          "applied": false
        }
      ]
    }
  }
}

Example Response (failed):

{
  "data": {
    "id": "job_01HX...",
    "type": "pricing_recalculate",
    "status": "failed",
    "error": {
      "code": "WORKER_TIMEOUT",
      "message": "Worker did not respond within the timeout window",
      "retry_count": 2
    }
  }
}

List Jobs

GET /api/ai-jobs

Query Parameters:

ParameterTypeDescription
typestringFilter by job type
statusstringFilter by status
start_datestringJobs created on or after
end_datestringJobs created on or before
limitintegerResults per page

Cancel Job

DELETE /api/ai-jobs/:jobId

Cancels a queued job. Jobs that are already running cannot be cancelled.

Response: HTTP 204 No Content.

Batch Dispatch

POST /api/ai-jobs/batch

Dispatch multiple jobs at once. Maximum 20 jobs per batch.

Request Body:

{
  "jobs": [
    {
      "type": "competitor_scan",
      "params": {"skus": ["SKU-001"], "marketplace": "amazon_us"}
    },
    {
      "type": "pricing_recalculate",
      "params": {"skus": ["SKU-001"], "marketplace": "amazon_us", "apply": true}
    }
  ],
  "sequential": true
}

Set "sequential": true to run jobs in order (job 2 starts after job 1 completes). Set to false (default) to run in parallel.

Response:

{
  "data": {
    "batch_id": "batch_01HX...",
    "jobs": [
      {"id": "job_01HX...", "type": "competitor_scan", "status": "queued"},
      {"id": "job_01HY...", "type": "pricing_recalculate", "status": "queued"}
    ]
  }
}

Polling Pattern

Recommended polling pattern for job completion:

async function waitForJob(jobId, intervalMs = 2000, timeoutMs = 300000) {
  const startTime = Date.now()
  while (Date.now() - startTime < timeoutMs) {
    const response = await fetch(`/api/ai-jobs/${jobId}`, {
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'X-Tenant-ID': tenantId
      }
    })
    const { data } = await response.json()
    if (data.status === 'completed') return data.result
    if (data.status === 'failed') throw new Error(data.error.message)
    await new Promise(resolve => setTimeout(resolve, intervalMs))
  }
  throw new Error('Job polling timeout')
}

Error Codes

CodeHTTP StatusDescription
JOB_NOT_FOUND404Job ID does not exist
INVALID_JOB_TYPE422Unknown job type
QUEUE_FULL429Job queue is at capacity; retry later
INSUFFICIENT_SCOPE403API key lacks ai-jobs:write scope
JOB_NOT_CANCELLABLE409Job is running and cannot be cancelled