Search via the API

In addition to the CRUD endpoints for Documents, search endpoints are also available within our JSON:API. With these endpoints you can perform semantic searches within your knowledge base and further refine the results with filters, facets, sorting, and pagination.

These search endpoints are designed for situations where simply retrieving a document by ID is not enough, but where you want to find relevant documents or document fragments based on a search query.

Authentication

To authorize HTTP requests to our system, we use a so-called long lived Bearer token.

Example of an Authorization header with a Bearer token:

Authorization: Bearer 31090db4198c2bf9f9a7d768bf6107a40f102d47534cb122b0
Authorization: Bearer 31090db4198c2bf9f9a7d768bf6107a40f102d47534cb122b0
Authorization: Bearer 31090db4198c2bf9f9a7d768bf6107a40f102d47534cb122b0

The endpoints are available per customer under their own subdomain, for example:

https://{client}.vragen.ai/api/v1/
https://{client}.vragen.ai/api/v1/
https://{client}.vragen.ai/api/v1/

The API expects the following headers with each request:

Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json

Search endpoints

There are two search endpoints available:

1. Search in documents

GET https://{client}.vragen.ai/api/v1/documents/search
GET https://{client}.vragen.ai/api/v1/documents/search
GET https://{client}.vragen.ai/api/v1/documents/search

This endpoint returns search results at the document level. Each result refers to a document from the knowledge base.

2. Search in document fragments

GET https://{client}.vragen.ai/api/v1/document-chunks/search
GET https://{client}.vragen.ai/api/v1/document-chunks/search
GET https://{client}.vragen.ai/api/v1/document-chunks/search

This endpoint returns search results at the chunk level. A chunk is a fragment of a document. This endpoint is useful when you want to retrieve more granular search results than at the full document level.

Although the source differs, both endpoints share the exact same request and response structure.

General request parameters

The following query parameters are supported:

query

Type: string
Optional

The natural language query or search term used for semantic searching.

Example:

?query=openingstijden gemeentehuis
?query=openingstijden gemeentehuis
?query=openingstijden gemeentehuis

maxDistance

Type: number
Optional
Value: between 0 and 1

This limits the maximum semantic distance of results. A lower value makes the search stricter.

Example:

?query=vergunning&maxDistance=0.4
?query=vergunning&maxDistance=0.4
?query=vergunning&maxDistance=0.4

page[offset]

Type: integer
Optional
Default: 0

The number of results to skip.

page[limit]

Type: integer
Optional
Default: determined by the platform

The maximum number of results to return.

Example:

?query=verlof&page[offset]=0&page[limit]=25
?query=verlof&page[offset]=0&page[limit]=25
?query=verlof&page[offset]=0&page[limit]=25

sort

Type: string
Optional

Sorting fields are specified as comma-separated values. Use:

  • fieldname for ascending sort

  • -fieldname for descending sort

  • +fieldname explicitly for ascending sort

Example:

?query=jaarverslag&sort=-date,title
?query=jaarverslag&sort=-date,title
?query=jaarverslag&sort=-date,title

Which sortable fields are available depends on the fields configured for the knowledge base.

fields[...]

Type: sparse fieldset
Optional

This allows you to limit the response fields.

For example, for documents/search you use:

fields[documents]=id,url,title,summary
fields[documents]=id,url,title,summary
fields[documents]=id,url,title,summary

For example, for document-chunks/search you use:

fields[document-chunks]=id,url,summary
fields[document-chunks]=id,url,summary
fields[document-chunks]=id,url,summary

You can also use the internal resource type directly:

fields[semantic-searchables]=id,url,title,summary
fields[semantic-searchables]=id,url,title,summary
fields[semantic-searchables]=id,url,title,summary

Note: The response internally uses the resource type semantic-searchables, but the API also accepts the aliases documents and document-chunks in fields[...] for these endpoints.

Filters

Using filter you can narrow down search results to documents or chunks that meet additional conditions.

Filters are provided as an array of objects. Each filter rule supports options including:

  • path: the name of the field you want to filter on

  • value: the value you are looking for

  • operator: the comparison operator

  • id: optional, for grouped filters

  • parent: optional, to link filters to a group

  • tag or tags: optional, to label filters

Available filter operators:

  • =

  • !=

  • >

  • >=

  • <

  • <=

  • LIKE

  • IN

  • ALL

  • NOT IN

  • IS NULL

Boolean operators are available for filter groups:

  • AND

  • OR

Which path values can you use?

The available filter fields depend on the setup of the client's knowledge base. In practice, these include:

  • metadata fields from meta_data

  • knowledge scope fields

  • system fields, such as source

Note:

  • metadata keys are stored internally in snake_case

  • a metadata field like publishDate therefore becomes publish_date

Simple filter example

Search only within documents where the metadata author is equal to SWIS:

GET https://{klant}.vragen.ai/api/v1/documents/search?query=homepage&filter[0][path]=author&filter[0][operator]==&filter[0][value]=SWIS
GET https://{klant}.vragen.ai/api/v1/documents/search?query=homepage&filter[0][path]=author&filter[0][operator]==&filter[0][value]=SWIS
GET https://{klant}.vragen.ai/api/v1/documents/search?query=homepage&filter[0][path]=author&filter[0][operator]==&filter[0][value]=SWIS

Filter example with list values

Search within documents that fall into one of multiple categories:

GET https://{klant}.vragen.ai/api/v1/documents/search?query=beleid&filter[0][path]=category&filter[0][operator]=IN&filter[0][value][]=beleid&filter[0][value][]=nieuws
GET https://{klant}.vragen.ai/api/v1/documents/search?query=beleid&filter[0][path]=category&filter[0][operator]=IN&filter[0][value][]=beleid&filter[0][value][]=nieuws
GET https://{klant}.vragen.ai/api/v1/documents/search?query=beleid&filter[0][path]=category&filter[0][operator]=IN&filter[0][value][]=beleid&filter[0][value][]=nieuws

Filter example with groups

Search for documents where:

  • source = website

  • AND (category = faq OR category = manual)

GET https://{klant}.vragen.ai/api/v1/documents/search?query=wachtwoord&filter[0][id]=group_root&filter[0][operator]=AND&filter[1][path]=source&filter[1][operator]==&filter[1][value]=website&filter[2][id]=group_categories&filter[2][parent]=group_root&filter[2][operator]=OR&filter[3][parent]=group_categories&filter[3][path]=category&filter[3][operator]==&filter[3][value]=faq&filter[4][parent]=group_categories&filter[4][path]=category&filter[4][operator]==&filter[4][value]=handleiding
GET https://{klant}.vragen.ai/api/v1/documents/search?query=wachtwoord&filter[0][id]=group_root&filter[0][operator]=AND&filter[1][path]=source&filter[1][operator]==&filter[1][value]=website&filter[2][id]=group_categories&filter[2][parent]=group_root&filter[2][operator]=OR&filter[3][parent]=group_categories&filter[3][path]=category&filter[3][operator]==&filter[3][value]=faq&filter[4][parent]=group_categories&filter[4][path]=category&filter[4][operator]==&filter[4][value]=handleiding
GET https://{klant}.vragen.ai/api/v1/documents/search?query=wachtwoord&filter[0][id]=group_root&filter[0][operator]=AND&filter[1][path]=source&filter[1][operator]==&filter[1][value]=website&filter[2][id]=group_categories&filter[2][parent]=group_root&filter[2][operator]=OR&filter[3][parent]=group_categories&filter[3][path]=category&filter[3][operator]==&filter[3][value]=faq&filter[4][parent]=group_categories&filter[4][path]=category&filter[4][operator]==&filter[4][value]=handleiding

Facets

Using facets allows you to return aggregations alongside search results. This is useful for filter interfaces in search flows, such as counts per category, author, or source.

Each facet rule supports:

  • path: the field to group by

  • limit: maximum number of buckets

  • min_count: minimum number of results per bucket

  • operator: AND or OR

  • exclude_tags: optional, to exclude filters with the same tags during facet calculation

Example:

GET https://{klant}.vragen.ai/api/v1/documents/search?query=parkeren&facets[0][path]=category&facets[0][limit]=5&facets[0][min_count]=1&facets[1][path]=source&facets[1][limit]=10
GET https://{klant}.vragen.ai/api/v1/documents/search?query=parkeren&facets[0][path]=category&facets[0][limit]=5&facets[0][min_count]=1&facets[1][path]=source&facets[1][limit]=10
GET https://{klant}.vragen.ai/api/v1/documents/search?query=parkeren&facets[0][path]=category&facets[0][limit]=5&facets[0][min_count]=1&facets[1][path]=source&facets[1][limit]=10

In the response, facet results are included in meta.facets.

Example request

The example below searches semantically in documents, limits results to the source website, requests facets for category, and sorts descending by date.

GET https://{klant}.vragen.ai/api/v1/documents/search?query=duurzaamheid&maxDistance=0.5&filter[0][path]=source&filter[0][operator]==&filter[0][value]=website&facets[0][path]=category&facets[0][limit]=10&sort=-date&page[offset]=0&page[limit]=10
GET https://{klant}.vragen.ai/api/v1/documents/search?query=duurzaamheid&maxDistance=0.5&filter[0][path]=source&filter[0][operator]==&filter[0][value]=website&facets[0][path]=category&facets[0][limit]=10&sort=-date&page[offset]=0&page[limit]=10
GET https://{klant}.vragen.ai/api/v1/documents/search?query=duurzaamheid&maxDistance=0.5&filter[0][path]=source&filter[0][operator]==&filter[0][value]=website&facets[0][path]=category&facets[0][limit]=10&sort=-date&page[offset]=0&page[limit]=10

Example response

The search endpoints return results as a JSON:API collection with the resource type semantic-searchables.

{
  "meta": {
    "total": 2,
    "limit": 10,
    "offset": 0,
    "facets": {
      "category": [
        {
          "filter": "handleiding",
          "count": 8
        },
        {
          "filter": "faq",
          "count": 3
        }
      ]
    }
  },
  "jsonapi": {
    "version": "1.0"
  },
  "links": {
    "self": "https://{klant}.vragen.ai/api/v1/documents/search"
  },
  "data": [
    {
      "type": "semantic-searchables",
      "id": "9001",
      "attributes": {
        "url": "https://www.domein-met-het-nieuwe-zoeken.nl/duurzaamheid",
        "favicon": "https://www.domein-met-het-nieuwe-zoeken.nl/favicon.ico",
        "summary": "Samenvatting of relevante inhoud van het gevonden resultaat.",
        "title": "Duurzaamheid",
        "external_reference": "scrapedPage:9001",
        "last_updated": "2026-05-15T12:00:00+00:00",
        "relevance_score": 0.92,
        "distance": 0.08,
        "knowledge_scopes": {
          "topic": "duurzaamheid"
        },
        "metadata_fields": {
          "category": "handleiding",
          "author": "Gemeente Voorbeeld"
        },
        "mime_type": "text/html"
      }
    }
  ]
}
{
  "meta": {
    "total": 2,
    "limit": 10,
    "offset": 0,
    "facets": {
      "category": [
        {
          "filter": "handleiding",
          "count": 8
        },
        {
          "filter": "faq",
          "count": 3
        }
      ]
    }
  },
  "jsonapi": {
    "version": "1.0"
  },
  "links": {
    "self": "https://{klant}.vragen.ai/api/v1/documents/search"
  },
  "data": [
    {
      "type": "semantic-searchables",
      "id": "9001",
      "attributes": {
        "url": "https://www.domein-met-het-nieuwe-zoeken.nl/duurzaamheid",
        "favicon": "https://www.domein-met-het-nieuwe-zoeken.nl/favicon.ico",
        "summary": "Samenvatting of relevante inhoud van het gevonden resultaat.",
        "title": "Duurzaamheid",
        "external_reference": "scrapedPage:9001",
        "last_updated": "2026-05-15T12:00:00+00:00",
        "relevance_score": 0.92,
        "distance": 0.08,
        "knowledge_scopes": {
          "topic": "duurzaamheid"
        },
        "metadata_fields": {
          "category": "handleiding",
          "author": "Gemeente Voorbeeld"
        },
        "mime_type": "text/html"
      }
    }
  ]
}
{
  "meta": {
    "total": 2,
    "limit": 10,
    "offset": 0,
    "facets": {
      "category": [
        {
          "filter": "handleiding",
          "count": 8
        },
        {
          "filter": "faq",
          "count": 3
        }
      ]
    }
  },
  "jsonapi": {
    "version": "1.0"
  },
  "links": {
    "self": "https://{klant}.vragen.ai/api/v1/documents/search"
  },
  "data": [
    {
      "type": "semantic-searchables",
      "id": "9001",
      "attributes": {
        "url": "https://www.domein-met-het-nieuwe-zoeken.nl/duurzaamheid",
        "favicon": "https://www.domein-met-het-nieuwe-zoeken.nl/favicon.ico",
        "summary": "Samenvatting of relevante inhoud van het gevonden resultaat.",
        "title": "Duurzaamheid",
        "external_reference": "scrapedPage:9001",
        "last_updated": "2026-05-15T12:00:00+00:00",
        "relevance_score": 0.92,
        "distance": 0.08,
        "knowledge_scopes": {
          "topic": "duurzaamheid"
        },
        "metadata_fields": {
          "category": "handleiding",
          "author": "Gemeente Voorbeeld"
        },
        "mime_type": "text/html"
      }
    }
  ]
}

Meaning of response fields

summary

For documents/search, this field contains a summary or representative snippet of the document.

For document-chunks/search, this field contains the text of the specific document fragment found as a search result.

relevance_score

A score indicating how relevant the result is to the search query.

distance

The semantic distance between the query and the result. Lower is generally better.

metadata_fields

The metadata associated with the document, where available.

knowledge_scopes

The knowledge scopes linked to the document, where available.

Practical considerations

  • Use documents/search when you want to show results at the document level.

  • Use document-chunks/search when you want to show the most relevant text fragment directly.

  • Keep snake_case in mind for metadata fields in filters and facets.

  • Not every visible response field is automatically filterable or sortable.

  • The available filter, facet, and sort fields depend on the configuration of the respective client's knowledge base.

Support

Using the information and examples above, you should have no trouble setting up a connection to our API search endpoints. If you have any further questions, please contact our support team at info@vragen.ai.