API Reference
Query and mutate data with the type-safe tRPC API.
Overview
Parser Run uses tRPC for end-to-end type safety. Your IDE knows the exact shape of every response—no codegen required.
Client Setup
import { createTRPCClient, httpBatchLink } from "@trpc/client";
import type { AppRouter } from "@parser-run/trpc";
const trpc = createTRPCClient<AppRouter>({
links: [
httpBatchLink({
url: "https://api.parser.run/trpc",
headers: () => ({
authorization: `Bearer ${apiKey}`,
}),
}),
],
});Projects
Manage scraping projects.
List Projects
const { projects } = await trpc.projects.list.query({
limit: 10,
offset: 0,
status: "active", // optional filter
});Get Project
const project = await trpc.projects.get.query({
id: "nike-price-tracker",
});Create Project
const project = await trpc.projects.create.mutate({
name: "Competitor Prices",
urls: ["https://competitor.com/products"],
schema: {
name: "text",
price: "number",
inStock: "boolean",
},
schedule: "daily",
});Jobs
Monitor and control scraping jobs.
Start Job
const job = await trpc.scraper.runScrape.mutate({
projectId: "nike-price-tracker",
});
// Returns job ID for status polling
console.log(job.id); // "job_xyz789"Get Job Status
const status = await trpc.scraper.getScrapeStatus.query({
jobId: "job_xyz789",
});
// status.stage: "discovery" | "acquisition" | "parsing" | "complete" | "failed"
// status.progress: 0-100
// status.recordsExtracted: numberList Recent Jobs
const { jobs } = await trpc.scraper.listJobs.query({
projectId: "nike-price-tracker",
limit: 10,
});Records
Query extracted data.
List Records
const { records, total } = await trpc.records.list.query({
projectId: "nike-price-tracker",
limit: 100,
offset: 0,
orderBy: "extractedAt",
orderDir: "desc",
});Query Records
const { records } = await trpc.records.query.query({
projectId: "nike-price-tracker",
filters: [
{ field: "price", operator: "lt", value: 100 },
{ field: "in_stock", operator: "eq", value: true },
],
orderBy: "price",
orderDir: "asc",
});Export Records
const csv = await trpc.records.export.query({
projectId: "nike-price-tracker",
format: "csv", // or "json"
});Authentication
API requests require an API key. Generate keys in Settings → API Keys.
Example Request
curl -X POST https://api.parser.run/trpc/projects.list \
-H "Authorization: Bearer pk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{"limit": 10}'Key types:
- • Read — Query projects, jobs, and records
- • Write — Create projects, start jobs
- • Admin — Full access including settings
Webhooks
Receive notifications when events occur.
Webhook Payload
// POST to your webhook URL
{
event: "job.completed",
timestamp: "2025-01-15T10:30:00Z",
data: {
projectId: "nike-price-tracker",
jobId: "job_xyz789",
recordsExtracted: 240,
duration: 847, // seconds
}
}
// Event types:
// - job.started
// - job.completed
// - job.failed
// - alert.triggeredError Handling
tRPC throws typed errors you can catch:
import { TRPCClientError } from "@trpc/client";
try {
await trpc.projects.get.query({ id: "nonexistent" });
} catch (error) {
if (error instanceof TRPCClientError) {
console.log(error.message); // "Project not found"
console.log(error.data?.code); // "NOT_FOUND"
}
}
// Common error codes:
// - UNAUTHORIZED: Invalid or missing API key
// - NOT_FOUND: Resource doesn't exist
// - BAD_REQUEST: Invalid parameters
// - RATE_LIMITED: Too many requestsRate Limits
API requests are rate limited by plan:
| Plan | Requests/min | Concurrent Jobs |
|---|---|---|
| Starter | 60 | 1 |
| Growth | 300 | 5 |
| Scale | 1000 | 20 |