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.

Filter grammar, operators, and ready-to-copy recipes for Search Jobs. For the main walkthrough (request/response, quickstart), see Search Jobs. For the full field catalog, see Reference. For sorting, pagination, field selection, and aggregations, see Pagination & sorting.
Replace YOUR_API_KEY in each example with your actual API key. All requests require the x-api-version: 2025-11-01 header.

Filter grammar

Every filter describes which individual job rows to keep. The API checks each job listing against your filter independently — it never groups or combines rows before filtering. There are two building blocks:
Building blockWhat it does
SearchCondition (leaf)Tests one field on one job row — e.g. title = "Software Engineer".
SearchConditionGroup (node)Combines conditions with and or or. Groups can nest inside other groups.
Exact-match AND on the same field always returns zero results. One listing has one title, so (title = "Software Engineer") AND (title = "Account Executive") can never match. This applies to = and in.
All-words operators ((.)) work fine in AND. Because (.) checks for individual words — not a contiguous substring — a query like (title (.) "Software Development") AND (title (.) "Software Engineer") matches any title containing all three words “Software”, “Development”, and “Engineer” (e.g. “Software Development Engineer”).
Need companies hiring for both role X and role Y (two different listings)? Run two separate queries and intersect company ids client-side. See Companies indexing both Software Engineers and Account Executives.

Single condition

{
    "filters": {
        "field": "job_details.category",
        "type": "=",
        "value": "Engineering"
    }
}

AND / OR group

{
    "filters": {
        "op": "and",
        "conditions": [
            {
                "field": "company.basic_info.company_id",
                "type": "=",
                "value": 631394
            },
            {
                "field": "job_details.category",
                "type": "=",
                "value": "Engineering"
            },
            {
                "field": "metadata.date_added",
                "type": "=>",
                "value": "2025-01-01"
            }
        ]
    }
}

Array-field filters and grouping

When you filter on a string-array field like company.basic_info.industries, the condition is satisfied if any element of the array matches.For example:
{ "field": "company.basic_info.industries", "type": "=", "value": "Technology, Information and Internet" }
This matches any company whose industries array contains that exact string. Use (.) to match words within any element.
When you group_by on an array field, each array element becomes its own bucket key. A company in two industries contributes one count to each of the two industry buckets — so the sum of bucket counts can exceed total_count for array columns.

Nested groups (SDR / BDR keyword search across multiple companies)

The long forms "Sales Development Representative" and "Business Development Representative" use (.) (all-words match), but the short acronym "SDR" uses [.] (exact phrase). Short acronyms with (.) can overmatch — e.g. "SDR" would also match "USDR". Use [.] for 2–3 character acronyms.
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": "in", "value": [631394, 631811, 673947] },
        { "field": "metadata.date_added",           "type": "=>", "value": "2025-01-01" },
        {
          "op": "or",
          "conditions": [
            { "field": "job_details.title", "type": "(.)", "value": "Sales Development Representative" },
            { "field": "job_details.title", "type": "[.]", "value": "SDR" },
            { "field": "job_details.title", "type": "(.)", "value": "Business Development Representative" }
          ]
        }
      ]
    },
    "fields": [
      "job_details.title",
      "company.basic_info.name",
      "location.raw",
      "metadata.date_added"
    ],
    "sorts": [{ "column": "metadata.date_added", "order": "desc" }],
    "limit": 2
  }'

Filter operators

Use the table below to pick the right type for each condition. Every operator works on indexed fields only.
Operatorvalue shapeMeaning
=scalar (string/number/boolean)Exact match.
!=scalarNot equal.
<scalar (numeric or ISO date)Less than.
=<scalar (numeric or ISO date)Less than or equal. Not <=.
>scalar (numeric or ISO date)Greater than.
=>scalar (numeric or ISO date)Greater than or equal. Not >=.
inarray of scalarsField value is any entry in the array.
not_inarray of scalarsField value is none of the entries in the array.
(.)stringCase-insensitive all-words match. Every word in the query must appear somewhere in the field, but not necessarily next to each other or in the same order. "Software Engineer" matches "Software Engineer", "Software Development Engineer", and "Engineer, Software Systems". A single word like "engineer" also matches "Engineering Manager". Great for broad keyword hunting in job_details.title or content.description.
[.]stringCase-insensitive exact-phrase match. The words must appear contiguously and in order. "Software Engineer" matches "Senior Software Engineer" but not "Software Development Engineer" (extra word in between) and not "Engineer Software" (wrong order). Use [.] when you need precision over recall.
Operator footguns.
  • Use => for greater-than-or-equal and =< for less-than-or-equal — they are not >= and <=.
  • in and not_in require JSON arrays, not comma-separated strings.
  • is_null / is_not_null are currently not implemented — request the field via fields and filter for null presence client-side.

Example queries

Use these recipes for public, indexed workflows beyond the basic examples.

Companies indexing both Software Engineers and Account Executives

Because filters operate on individual job rows, you cannot ask for “companies with both roles” in a single query. Instead, run two bounded-window aggregations and intersect the company ids client-side.
Watch out for short-acronym false positives. (.) is an all-words match, so a query of "AE" in job_details.title can also match unrelated titles. Prefer [.] for 2–3 character acronyms.
1

Query 1 — companies with Software Engineer listings

{
    "filters": {
        "op": "and",
        "conditions": [
            { "field": "metadata.date_added", "type": "=>", "value": "2025-01-01" },
            { "field": "metadata.date_added", "type": "<", "value": "2026-01-01" },
            {
                "op": "or",
                "conditions": [
                    { "field": "job_details.title", "type": "(.)", "value": "Software Engineer" },
                    { "field": "job_details.title", "type": "[.]", "value": "SWE" }
                ]
            }
        ]
    },
    "limit": 0,
    "aggregations": [
        { "type": "group_by", "column": "company.basic_info.company_id", "agg": "count", "size": 500 }
    ]
}
2

Query 2 — companies with Account Executive listings

{
    "filters": {
        "op": "and",
        "conditions": [
            { "field": "metadata.date_added", "type": "=>", "value": "2025-01-01" },
            { "field": "metadata.date_added", "type": "<", "value": "2026-01-01" },
            {
                "op": "or",
                "conditions": [
                    { "field": "job_details.title", "type": "(.)", "value": "Account Executive" },
                    { "field": "job_details.title", "type": "[.]", "value": "AE" }
                ]
            }
        ]
    },
    "limit": 0,
    "aggregations": [
        { "type": "group_by", "column": "company.basic_info.company_id", "agg": "count", "size": 500 }
    ]
}
3

Intersect the company ids client-side

engineering_ids = {b["key"] for b in response_1["aggregations"][0]["buckets"]}
ae_ids = {b["key"] for b in response_2["aggregations"][0]["buckets"]}

both = engineering_ids & ae_ids

Mid-market companies indexing SDR listings

Combine an inclusive headcount range with keyword search on the title field.
{
    "filters": {
        "op": "and",
        "conditions": [
            { "field": "company.headcount.total", "type": "=>", "value": 51 },
            { "field": "company.headcount.total", "type": "=<", "value": 500 },
            { "field": "metadata.date_added", "type": "=>", "value": "2025-01-01" },
            {
                "op": "or",
                "conditions": [
                    { "field": "job_details.title", "type": "(.)", "value": "Sales Development Representative" },
                    { "field": "job_details.title", "type": "[.]", "value": "SDR" },
                    { "field": "job_details.title", "type": "(.)", "value": "Business Development Representative" }
                ]
            }
        ]
    },
    "fields": [
        "crustdata_job_id",
        "job_details.title",
        "company.basic_info.crustdata_company_id",
        "company.basic_info.name",
        "company.basic_info.primary_domain",
        "company.headcount.total",
        "location.raw",
        "metadata.date_added"
    ],
    "sorts": [{ "column": "metadata.date_added", "order": "desc" }],
    "limit": 50
}

Companies that closed a Series B between two dates and are indexing new listings

{
    "filters": {
        "op": "and",
        "conditions": [
            { "field": "company.funding.last_round_type", "type": "=", "value": "series_b" },
            { "field": "company.funding.last_fundraise_date", "type": "=>", "value": "2025-01-01" },
            { "field": "company.funding.last_fundraise_date", "type": "<", "value": "2025-07-01" },
            { "field": "metadata.date_added", "type": "=>", "value": "2025-01-01" }
        ]
    },
    "fields": [
        "job_details.title",
        "company.basic_info.crustdata_company_id",
        "company.basic_info.name",
        "company.basic_info.primary_domain",
        "company.funding.last_round_type",
        "company.funding.last_fundraise_date",
        "company.funding.total_investment_usd"
    ],
    "sorts": [
        { "column": "company.funding.last_fundraise_date", "order": "desc" }
    ],
    "limit": 100
}

Hiring volume by workplace type in the United States

Country values are not normalized. location.country can appear as "USA", "United States", or "United States of America". The in array below covers the three most common forms, but for full coverage you should first run a group_by on location.country and collect the exact bucket keys present in your dataset slice.
{
    "filters": {
        "op": "and",
        "conditions": [
            {
                "field": "location.country",
                "type": "in",
                "value": ["USA", "United States", "United States of America"]
            },
            { "field": "metadata.date_added", "type": "=>", "value": "2025-01-01" },
            { "field": "metadata.date_added", "type": "<", "value": "2026-01-01" }
        ]
    },
    "limit": 0,
    "aggregations": [
        { "type": "group_by", "column": "job_details.workplace_type", "agg": "count", "size": 10 }
    ]
}

Full-text keyword hunt in job descriptions

{
    "filters": {
        "op": "and",
        "conditions": [
            { "field": "content.description", "type": "(.)", "value": "kubernetes" },
            { "field": "metadata.date_added", "type": "=>", "value": "2025-01-01" }
        ]
    },
    "fields": [
        "job_details.title",
        "company.basic_info.name",
        "location.raw",
        "metadata.date_added"
    ],
    "sorts": [{ "column": "metadata.date_added", "order": "desc" }],
    "limit": 20
}

Next steps

  • Pagination & sorting — sorting, cursor pagination, field selection, and aggregations.
  • Reference — full field catalog, id map, bucket metadata, and errors.
  • Search Jobs — back to the main Search page.