Documentation
Official client libraries for Node.js/TypeScript and Python. Full async support, typed responses, automatic retry, and batch helpers built in.
npm install @seekapi/sdk pnpm add @seekapi/sdk
pip install seekapi poetry add seekapi
Node.js / TypeScript
import { SeekAPI } from '@seekapi/sdk'; const client = new SeekAPI({ apiKey: process.env.SEEKAPI_KEY, }); const job = await client.jobs.submit( 'linkedin-profile', { profileUrl: 'https://linkedin.com/in/example' } ); const result = await job.waitForCompletion(); console.log(result.data);
Python
import os from seekapi import SeekAPI client = SeekAPI( api_key=os.environ["SEEKAPI_KEY"] ) job = client.jobs.submit( "linkedin-profile", {"profile_url": "https://linkedin.com/in/example"} ) result = job.wait_for_completion() print(result.data)
| Node.js | Python | Description |
|---|---|---|
new SeekAPI({ apiKey }) | SeekAPI(api_key=…) | Create a new client instance. Reads SEEKAPI_KEY env var if apiKey is omitted. |
client.jobs.submit(workerId, input) | client.jobs.submit(worker_id, input) | Submit an async job. Returns a Job object immediately. |
client.jobs.get(jobUuid) | client.jobs.get(job_uuid) | Fetch current status and result for a job UUID. |
job.waitForCompletion({ timeout? }) | job.wait_for_completion(timeout=None) | Poll until the job reaches a terminal state. Returns full job object with result. |
client.jobs.submitBatch(workerId, inputs[]) | client.jobs.submit_batch(worker_id, inputs) | Submit multiple jobs in parallel. Returns array of Job objects. |
client.workers.list({ category? }) | client.workers.list(category=None) | List all available marketplace workers. |
client.workers.get(workerId) | client.workers.get(worker_id) | Get full schema and pricing for a specific worker. |
client.credits.balance() | client.credits.balance() | Return current credit balance and monthly usage summary. |
Submit thousands of jobs concurrently with submitBatch. The SDK handles
concurrency limits, retries, and result collection automatically.
Node.js
const profiles = [ 'https://linkedin.com/in/user1', 'https://linkedin.com/in/user2', // … up to 10,000 URLs ]; const jobs = await client.jobs.submitBatch( 'linkedin-profile', profiles.map(url => { profileUrl: url }), { concurrency: 20 } ); const results = await Promise.all( jobs.map(j => j.waitForCompletion()) );
Python
profiles = [
"https://linkedin.com/in/user1",
"https://linkedin.com/in/user2",
# … up to 10,000 URLs
]
jobs = client.jobs.submit_batch(
"linkedin-profile",
[{"profile_url": u} for u in profiles],
concurrency=20,
)
results = [j.wait_for_completion() for j in jobs] Node.js
import { SeekAPI, RateLimitError, InsufficientCreditsError, JobTimeoutError, } from '@seekapi/sdk'; try { const job = await client.jobs.submit(…); const result = await job.waitForCompletion(); } catch (err) { if (err instanceof RateLimitError) { await sleep(err.retryAfter); } else if (err instanceof InsufficientCreditsError) { console.error('Buy more credits'); } else { throw err; } }
Python
from seekapi import ( SeekAPI, RateLimitError, InsufficientCreditsError, JobTimeoutError, ) try: job = client.jobs.submit(…) result = job.wait_for_completion() except RateLimitError as e: time.sleep(e.retry_after) except InsufficientCreditsError: print("Buy more credits")
| Error class | When thrown |
|---|---|
AuthError | Invalid or missing API key (HTTP 401). |
InsufficientCreditsError | Not enough credits to run the job (HTTP 402). |
WorkerNotFoundError | Worker ID does not exist (HTTP 404). |
ValidationError | Input failed worker schema validation (HTTP 422). |
RateLimitError | Too many requests. Access retry_after property (HTTP 429). |
JobTimeoutError | Job exceeded maximum duration. No credits charged. |
SeekAPIError | Base class for all SDK errors. Check .status and .message. |
Instead of polling, provide a webhook URL when submitting a job.
Use the SDK's built-in helper to verify the signature and parse the payload.
Express (Node.js)
import { verifyWebhook } from '@seekapi/sdk'; app.post('/hooks/seek', (req, res) => { const event = verifyWebhook( req.body, req.headers['x-seekapi-signature'], process.env.SEEKAPI_WEBHOOK_SECRET ); if (event.status === 'completed') { await processResult(event.result); } res.sendStatus(200); });
FastAPI (Python)
from seekapi import verify_webhook from fastapi import Request @app.post("/hooks/seek") async def webhook(request: Request): body = await request.body() sig = request.headers["x-seekapi-signature"] event = verify_webhook(body, sig, SECRET) if event["status"] == "completed": await process_result(event["result"]) return {"ok": True}
A worker is a directory containing a seekapi.yaml file (schema + metadata) and
a handler function. The SDK exposes the runWorker helper to validate inputs
and forward executions to your handler.
seekapi.yaml
id: my-email-validator
title: Email Validator
description: Verify any email address without sending a message.
version: 1.0.0
category: utilities
input:
email:
type: string
description: Email address to validate
required: true
deep_check:
type: boolean
description: Perform MX + SMTP EHLO check
default: false
output:
valid:
type: boolean
deliverable:
type: boolean
provider:
type: string
pricing:
per_job: 1 handler.ts
import { runWorker, WorkerContext } from '@seekapi/sdk'; interface Input { email: string; deepCheck?: boolean; } export default runWorker( async (input: Input, ctx: WorkerContext) => { ctx.log(`Checking ${input.email}`); const result = await validateEmail(input); return result; } );
seekapi deploy --watch from the worker directory. Seek API spins up a sandboxed container and routes test jobs to it in real time. When ready, run seekapi publish to submit for marketplace review.