Coding agent documentation index Fetch the complete documentation index at: https://docs.worklittle.com/docs-agent-manifest.json Use this file to discover all available pages before exploring further.

SDK

TypeScript and Python clients for api.worklittle.com. Same key, same resources. Language tabs below.

Install

npm install worklittle
export WORKLITTLE_API_KEY="sk-wl-api01-..."

Import as worklittle. To work from the monorepo instead: cd packages/sdk-js && npm install && npm run build.

Authentication

Bearer token. Create a key in the Worklittle Business under API keys.

Authorization: Bearer sk-wl-api01-...

For the SDK and CLI, set WORKLITTLE_API_KEY. Prefer the env var over --api-key so the key does not appear in process lists. Do not point --base-url at hosts you do not trust. Public board GETs and public survey submit do not require a key.

Quickstart

import { createWorklittle } from "worklittle";

const wl = createWorklittle(); // reads WORKLITTLE_API_KEY
const page = await wl.jobs.search({ q: "software engineer", limit: 3 });

Filters match GET /jobs. Title exclusions use a leading dash in title / q (-Senior). Employer exclusions use the same pattern on company (-lucid-motors):

await wl.jobs.search({
  title: "software engineer, -senior",
  company: "-lucid-motors,-tesla",
  limit: 10,
});

Equivalent HTTP:

curl -s "https://api.worklittle.com/jobs?q=software+engineer&limit=3" \
  -H "Authorization: Bearer $WORKLITTLE_API_KEY"

Search > detail

const page = await wl.jobs.search({ q: "software engineer", limit: 3 });
const rows = (page as { data?: Array<{ job_id?: string; id?: string }> }).data ?? [];
const id = rows[0]?.job_id || rows[0]?.id;
const detail = await wl.jobs.get(String(id));

Response (GET /jobs):

{
  "data": [
    {
      "job_id": "…",
      "title": "Software Engineer",
      "company_name": "Example Co",
      "location": "Remote"
    }
  ],
  "meta": { "next_cursor": "…" }
}

List rows are snippets. Use GET /jobs/:id for the full posting. See Search jobs.

Board > apply

YOUR_ORG_SLUG is the employer board slug (same as careers URLs).

import { createWorklittle, jobCareersPath } from "worklittle";

const wl = createWorklittle();
const company = "YOUR_ORG_SLUG";
const board = (await wl.boards.get(company)) as {
  jobs: Array<{ id: string; slug?: string }>;
};
const jobRef = board.jobs[0]!.slug || board.jobs[0]!.id;
const job = await wl.boards.getJob(company, jobRef);
// job.application_fields = form schema
await wl.boards.submitApplication(company, job as never, {
  name: "Alex Rivera",
  email: "alex@example.com",
});
jobCareersPath(board.jobs[0]!); // /careers/{slug}

See Embedded job board.

Candidates > profile

Requires a key with jobs:applications for your org.

const listed = await wl.candidates.list({ limit: 10 });
const detail = await wl.candidates.get("CANDIDATE_ID");
curl -s "https://api.worklittle.com/candidates?limit=10" \
  -H "Authorization: Bearer $WORKLITTLE_API_KEY"
curl -s "https://api.worklittle.com/candidates/CANDIDATE_ID" \
  -H "Authorization: Bearer $WORKLITTLE_API_KEY"

See Manage candidates.

Resources

| Method | HTTP | Docs |
| --- | --- | --- |
| `wl.jobs.search` / `get` | `GET /jobs`, `GET /jobs/:id` | [Search jobs](/business/api/search-jobs) |
| `wl.companies.search` | `GET /companies` | [Search companies](/business/api/search-companies) |
| `wl.boards.get` / `getJob` / `apply` | `/business/jobs/company/:company/…` | [Public job board](/business/api/public-job-board) |
| `wl.apply.submit` | `POST /jobs/:id/apply` | [Apply for jobs](/business/api/apply-for-jobs) |
| `wl.apply.startWithAi` / `getWithAiSession` / `continueWithAi` / `approveWithAiSubmit` / `stopWithAi` | `/jobs/apply` | [Apply for jobs](/business/api/apply-for-jobs) |
| `wl.candidates.list` / `get` | `GET /candidates`, `GET /candidates/:id` | [Manage candidates](/business/api/manage-candidates) |
| `wl.employees.*` | `/employees` | [Manage organization](/business/api/manage-organization) |
| `wl.jobListings.*` / `wl.employerJobs.*` | `/business/jobs`, `/business/jobs` | [Post a job](/business/api/post-a-job) |
| `wl.surveys.*` | `/business/surveys` | [Surveys](/business/api/surveys) |
| `wl.documents.*` | `/business/documents` | [Documents](/business/api/documents) |
| `wl.attendance.*` | `/attendance` | [Attendance](/business/api/attendance) |
| `wl.webhooks.*` | `/webhooks` | [Webhooks](/business/webhooks/integration) |
| `wl.resumes.*` / `wl.coverLetters.*` | `POST /jobs/resumes`, `POST /jobs/cover-letters` | [Create resumes](/business/api/create-resumes) |

Webhooks

import { verifyWebhookSignature } from "worklittle";

const ok = verifyWebhookSignature({
  signatureHeader: req.headers["worklittle-webhook-signature"] as string,
  timestamp: req.headers["worklittle-webhook-timestamp"] as string,
  rawBody,
  secret: process.env.WORKLITTLE_WEBHOOK_SECRET!,
});

See Webhook integration.

Errors

Throws WorklittleError with status, code, message, and requestId when present.

| Status | Meaning |
| --- | --- |
| **429** | Rate limited; client retries using `Retry-After` |
| **402** | Payment required (failed card or monthly limit) - do not retry |
| **401 / 403** | Invalid key or missing scope |