← Back to API docs

Docs

Search API

The Search API provides managed full-text search with App Engine Search semantics: structured documents; text, atom, number, date, and geo fields; a boolean query language; facets; sorting; and pagination. All paths below are relative to a search instance you provision in the console.

Authentication and base URL

Send requests to https://api.altengine.net with an organization API key as a bearer token. Reads require a read grant, writes a write grant, and deletes a full grant — see Authentication.

Authorization: Bearer ae_yourkeyid.your-api-key-secret

Every path is scoped to an instance: /v1/search/{instance}/…. Within an instance, documents live in named indexes. An optional namespace partitions data for multi-tenancy; set it with a ?namespace= query parameter or an X-Namespace header (the default namespace is empty).

Endpoints

Search API endpoints
Method & pathPurpose
PUT /v1/search/{instance}/indexes/{index}/documentsBatch put documents (creates the index on first write).
GET /v1/search/{instance}/indexes/{index}/documents/{id}Get one document by id.
GET /v1/search/{instance}/indexes/{index}/documentsList documents in id order.
POST /v1/search/{instance}/indexes/{index}/documents/deleteBatch delete documents by id.
POST /v1/search/{instance}/indexes/{index}/searchRun a search query.
GET /v1/search/{instance}/indexes/{index}/schemaGet the union field schema for an index.
GET /v1/search/{instance}/indexesList indexes in the instance.
DELETE /v1/search/{instance}/indexes/{index}Drop an index and all its documents.

Documents

A document has a string id, an optional numeric rank (used as the default sort — descending — when a query specifies no sort), a list of fields, and an optional list of facets. Fields are multi-valued and dynamic: two documents in the same index may carry different fields.

{
  "id": "f1",
  "rank": 12345,
  "fields": [
    { "name": "title",    "type": "text",   "value": "Up in the Air" },
    { "name": "genre",    "type": "atom",   "value": "drama" },
    { "name": "rating",   "type": "number", "value": 4 },
    { "name": "released", "type": "date",   "value": "2009-12-04" },
    { "name": "loc",      "type": "geo",    "value": { "lat": 37.77, "lng": -122.41 } }
  ],
  "facets": [
    { "name": "genre", "type": "atom",   "value": "drama" },
    { "name": "year",  "type": "number", "value": 2009 }
  ]
}

Field types

Supported field types
TypeDescription
textTokenized full-text; supports term, phrase, and stem matching.
htmlLike text, but tags are stripped before tokenizing.
atomAn exact-match string (not tokenized). Up to 500 bytes.
numberA numeric value; supports range comparisons and sorting.
dateAn YYYY-MM-DD date; supports range comparisons and sorting.
geoA { "lat", "lng" } point; supports distance() filtering.
tokenprefixTokenized text with prefix matching (autocomplete over words).
untokenprefixWhole-value prefix matching (autocomplete over a full string).

Put documents

Send up to 200 documents per request. Putting a document with an existing id replaces it. The response returns the ids written.

curl -X PUT https://api.altengine.net/v1/search/catalog/indexes/films/documents \
  -H "Authorization: Bearer $ALTENGINE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "documents": [ { "id": "f1", "fields": [ { "name": "title", "type": "text", "value": "Up in the Air" } ] } ] }'

# → { "ids": ["f1"] }

Get, list, and delete

# Get one document
GET /v1/search/catalog/indexes/films/documents/f1
# → { "document": { … } }

# List documents (id order). Params: start_id, include_start, limit, ids_only
GET /v1/search/catalog/indexes/films/documents?limit=50
# → { "documents": [ … ] }   (or { "ids": [ … ] } when ids_only=true)

# Batch delete by id (requires a full grant)
POST /v1/search/catalog/indexes/films/documents/delete
{ "ids": ["f1", "f2"] }
# → { "deleted": 2 }

Search

Post a search request to an index. Only query is required; an empty query matches all documents.

{
  "query": "genre:comedy rating > 3",
  "limit": 20,
  "offset": 0,
  "ids_only": false,
  "returned_fields": ["title", "rating"],
  "sort": [{ "expr": "rating", "desc": true, "default": 0 }],
  "facet_discover": 5,
  "facet_refinements": [{ "name": "genre", "value": "scifi" }],
  "total_hits_accuracy": 1000
}

Request fields

Search request fields
FieldDescription
queryThe query string (see Query language). Empty matches all.
limitPage size. Default 20, max 1000. 0 returns counts and facets only.
offsetResult offset. Max 1000. Prefer cursor for deep pagination.
cursorOpaque cursor from a prior response's cursor field; fetches the next page.
ids_onlyWhen true, results omit the document body and return ids only.
returned_fieldsRestrict returned documents to these field names.
sortArray of { expr, desc, default }; sorts by a field or expression. Falls back to rank.
facet_discoverAuto-discover up to N of the most common facets over the matches.
facet_refinementsArray of { name, value } to constrain results to a facet value.
total_hits_accuracyCount matches exactly up to this many. Default 20, max 10000.

Response

{
  "total_hits": 42,
  "total_hits_exact": true,
  "returned": 1,
  "results": [
    {
      "id": "f1",
      "rank": 12345,
      "score": 1.7,
      "document": {
        "id": "f1",
        "fields": [
          { "name": "title", "type": "text", "value": "Up in the Air" }
        ]
      }
    }
  ],
  "cursor": "eyJvIjoyMH0",
  "facets": [
    {
      "name": "genre",
      "type": "atom",
      "values": [
        { "value": "drama",  "count": 12 },
        { "value": "comedy", "count": 8 }
      ]
    }
  ]
}

total_hits is the number of matches, counted exactly only up to total_hits_accuracy. When total_hits_exact is false, total_hits is a lower bound — render it as "N+". Pagination is independent of the count: a cursor is present whenever more pages remain, so keep following it until it is absent.

Query language

The query language mirrors App Engine's Search syntax. Terms are combined with implicit AND.

Query language forms and examples
FormExample
Bare termair
Field scopetitle:air, genre = "sci fi"
Numeric / date comparerating > 3, released < 2011-02-28
Booleancomedy OR drama, NOT scifi, -scifi
Groupinggenre:(comedy OR drama)
Phrase"very important"
Stemming~running
Geo distancedistance(loc, geopoint(37.7, -122.4)) < 1000

Facets

Attach facets to documents to enable faceted navigation. Set facet_discover in a search to have altengine return the most common facet values over the matches, then pass the ones a user picks back as facet_refinements to narrow the result set. Atom facets return value counts; number facets return half-open [min, max) ranges with counts.

Limits

Search API limits
LimitValue
Documents per put200
Ids per delete200
Document id length500 bytes
Atom value length500 bytes
Index name length100 bytes
Search limit1000 (default 20)
Search offset1000
total_hits_accuracy10000 (default 20)

Index and document ids must be printable ASCII, may not start with !, and may not use the reserved __*__ form.