Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.crustdata.com/llms.txt

Use this file to discover all available pages before exploring further.

Use this when you need to find, segment, or count job listings across the full Crustdata job dataset — for hiring-trend analysis, building target account lists from recently indexed hiring activity, monitoring specific roles, or powering a dashboard.
metadata.date_added is when Crustdata first indexed the listing, not the employer-posted timestamp. Every query in this page that filters on metadata.date_added is asking about indexing time, not the employer’s actual publication date. Treat this endpoint as a query interface over Crustdata’s indexed dataset, not as a direct poll of an employer-managed listings feed.
POST https://api.crustdata.com/job/search
Replace YOUR_API_KEY in each example with your actual API key. All requests require the x-api-version: 2025-11-01 header.

Job record mental model

Every job listing returned by Search Jobs is a single Job object with five top-level groups:
  • crustdata_job_id and job_details — The stable job id plus the posting’s own metadata: title, category, URL, workplace type, and number of openings.
  • company — The hiring company’s firmographics at index time: basic info, headcount, followers, revenue, funding, locations, and competitors. No extra /company/enrich call required.
  • location — The job’s advertised location (city, state, country, raw string), not the company HQ.
  • content — Full job description text. Use the (.) filter operator on content.description to keyword-hunt.
  • metadata — Indexing timestamps: date_added for when the listing first appeared and date_updated for the most recent refresh. These are your primary sort and filter columns for recent windows.
Jobs ID cheat sheet. The Jobs APIs use three id concepts — keep them straight:
  • crustdata_job_id — the Crustdata job identifier. Returned on every Job. Use it as your dedupe key.
  • company.basic_info.crustdata_company_id — the Crustdata company identifier returned on every Job.
  • company.basic_info.company_id (filter alias) — the dot-path used in filters and aggregations.column for indexed Search Jobs. It points to the same integer as company.basic_info.crustdata_company_id. This alias is not sortable; for deterministic pagination, sort on metadata.date_added instead.
When you group_by on company.basic_info.company_id, each bucket also returns metadata.company_name, metadata.company_website_domain, and metadata.linkedin_id for labeling.

At a glance

DetailValue
EndpointPOST https://api.crustdata.com/job/search
AuthAuthorization: Bearer YOUR_API_KEY
API versionx-api-version: 2025-11-01 header (required)
BodyRequired. Send {} to match the whole dataset; every realistic query uses filters.
Body keysfilters, cursor, limit (0–1000, default 20), sorts, fields, aggregations — all optional
Response{ "job_listings": [ Job, ... ], "next_cursor": string?, "total_count": integer?, "aggregations"?: [ ... ] }
Errors400 invalid request · 401 unauthorized · 500 internal

Guaranteed contract vs current behavior

TopicWhat it means
Endpoint, HTTP method, auth headersPOST /job/search, bearer auth, x-api-version: 2025-11-01.
Request body shapeOptional filters, cursor, limit, sorts, fields, aggregations. filters is a SearchCondition or a SearchConditionGroup.
Response body shape{ "job_listings", "next_cursor", "total_count", "aggregations"? }. Aggregation-only queries return "job_listings": [].
Supported operators=, !=, <, =<, >, =>, in, not_in, is_null, is_not_null, (.), [.]. See Filter operators.
limit bounds and defaultMinimum 0, maximum 1000, default 20. Set limit: 0 when you only want aggregations.
Error status codes400, 401, 500.
Indexed-field allowlistOnly indexed fields can appear in filters, sorts, or aggregations.column. See Reference for the detailed catalog, or Common indexed fields for the most-used subset.
Pricing and rate limitsSee Pricing and Rate limits for current numbers.

Filters & recipes

Filter grammar, operators, and example queries like “SDR hiring in mid-market”, “companies that closed Series B”, full-text keyword hunts.

Pagination & sorting

Sorting, cursor-based pagination, field selection, and aggregations with count and group_by.

Reference

Common indexed fields, annotated Job example, full field catalog, id map, bucket metadata, errors.

Request body

ParameterTypeRequiredDefaultDescription
filtersobjectNoSingle SearchCondition or nested SearchConditionGroup. Omit to match all indexed jobs.
cursorstringNoOpaque cursor from a prior response’s next_cursor. Pass it to fetch the next page with the same filter, sort, and field set.
limitintegerNo20Rows per page. Min 0, max 1000. Use 0 for aggregation-only queries.
sortsarray of SearchSortNoOrdering rules. Each item has column (dot-path) and order (asc or desc). Sorts are applied in array order.
fieldsstring[]Noall fieldsDot-paths to include in each returned job. Omit to return everything. Always specify fields in production for smaller payloads and faster responses.
aggregationsarray of AggregationRequestNoRoll-up queries. Supports count and group_by. Use with limit: 0 if you only want counts.

Response body

FieldTypeDescription
job_listingsJob[]Matching job listings for the current page. Empty array [] when limit is 0 or when an aggregation-only query is made.
next_cursorstring or nullOpaque cursor to fetch the next page. null when there are no more pages.
total_countinteger or nullTotal number of jobs matching the filter across all pages. Can be null for very broad queries where computing an exact total would be prohibitively expensive — never assume it is populated.
aggregationsarrayAggregation results, present only when the request included an aggregations array.

Rate limits and credits

Current pricing for indexed Jobs Search:
Pricing: 0.03 credits per result returned. A request with no results does not consume credits.
Default rate-limit is 15 requests per minute. Send an email to gtm@crustdata.co to discuss higher limits if needed for your use case.

Your first search: filter by company and title

Find the most recent Software Engineer listings at Stripe (filtered via the company.basic_info.company_id alias, which maps to crustdata_company_id = 631394).
curl --request POST \
  --url https://api.crustdata.com/job/search \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --header 'x-api-version: 2025-11-01' \
  --data '{
    "filters": {
      "op": "and",
      "conditions": [
        { "field": "company.basic_info.company_id", "type": "=", "value": 631394 },
        { "field": "job_details.title",              "type": "=", "value": "Software Engineer" }
      ]
    },
    "fields": [
      "job_details.title",
      "job_details.url",
      "company.basic_info.name",
      "location.raw",
      "metadata.date_added"
    ],
    "sorts": [
      { "column": "metadata.date_added", "order": "desc" }
    ],
    "limit": 2
  }'
Always send fields. The full Job schema is large (firmographics
  • location + description + metadata). Fetching only the dot-paths you need keeps responses small, fast, and predictable.

Which search pattern should I use?

Use Search Jobs. You can slice millions of indexed job listings by company, title, category, location, date, or any other indexed field — and roll up results with count or group_by aggregations. Pair it with cursor-based pagination to walk through large result sets.

What’s next

  • Learn filter patterns — see Filters & recipes for filter grammar, operators, and example queries.
  • Paginate and aggregate — see Pagination & sorting for cursor pagination, sorting, field selection, and aggregations.
  • Look up fields — see Reference for the full Job catalog, id map, bucket metadata, and errors.
  • Fetch fresh listings for one company — see Live Search.
  • Inspect the full schema — read the OpenAPI reference.