Kern logoKern

API Reference

Endpoints, requests, and error handling

Production-ready API contract for task creation, status polling, and evidence retrieval.

Base URL

https://api.kernprotocol.com

Authentication

All requests require X-API-Key header with your server-side API key.

POST /v1/tasks

Create a new task with idempotency protection.

Request

POST /v1/tasks
X-API-Key: your_api_key
Idempotency-Key: unique-request-id
Content-Type: application/json

{
  "title": "Store verification",
  "instructions": "Capture storefront photo and status",
  "location": {
    "lat": -12.0464,
    "lng": -77.0428
  }
}

Response (201)

{
  "id": "task_abc123",
  "status": "pending",
  "createdAt": "2026-02-14T22:00:00Z"
}

Idempotency

Reuse the same Idempotency-Key on retry to avoid duplicate task creation.

GET /v1/tasks/:id

Retrieve task status and evidence.

Request

GET /v1/tasks/task_abc123
X-API-Key: your_api_key

Response (200)

{
  "id": "task_abc123",
  "status": "completed",
  "evidence": {
    "type": "photo",
    "url": "https://...",
    "metadata": { "timestamp": "2026-02-14T22:05:00Z" }
  },
  "decision": {
    "outcome": "approved",
    "confidence": 0.95
  }
}

GET /v1/tasks

List tasks with pagination.

Request

GET /v1/tasks?limit=20&cursor=next_page_token
X-API-Key: your_api_key

Error Codes

CodeMeaningAction
400Invalid request payloadFix schema validation errors
401Authentication failureVerify API key is correct
404Resource not foundCheck task ID
409Idempotency key conflictReuse original request shape or use new key
429Rate limit exceededApply exponential backoff
5xxServer errorRetry with circuit breaker

Rate Limiting

Handle 429 responses with exponential backoff and preserve idempotency keys on retry.

SDK Usage

import { KernClient } from "@kernprotocol/sdk";

const kern = new KernClient({
  apiKey: process.env.KERN_API_KEY!,
});

const task = await kern.tasks.create({
  title: "Store verification",
  instructions: "Capture photo",
  location: { lat: -12.0464, lng: -77.0428 },
}, {
  idempotencyKey: crypto.randomUUID(),
});

const status = await kern.tasks.get(task.id);