Galya Docs
Galya (Beta)Use cases

Reranking, Search, and Discovery over content

Personalize search results and reorder candidate lists for a specific user.

Personalize what a user sees over a catalog of content: create the user, link a few items they like, and let Galya rank or reorder for their taste.

Who this is for

Ecommerce, OTAs (online travel agencies), dating apps, and any tasteful AI assistant or agent that needs to surface the right item to the right person.

The flow

  1. Create the user once with POST /v1/entity.
  2. Add content items with POST /v1/index, each linked to the user via entity_id.
  3. Personalize search with POST /v1/search using relative_to_entity_id and in_terms_of_entity_type=content.
  4. Reorder your own shortlist with POST /v1/rerank.

entity_id on /v1/index is a link target, not a new id

The entity_id you pass in the /v1/index body is an existing user id you're attaching this content to. The entity_id returned in the response is a new hashed id for the content item Galya just created (derived from the content's URL). Do not confuse the two.

Phase 1 vs Phase 2 indexing

POST /v1/index returns immediately once the item is embedded and linked (Phase 1). A background enrichment job then runs (Phase 2, roughly 30 seconds) to fill in a richer name and description from the URL. A GET /v1/entity?entity_id=… right after POST /v1/index may show URL-host-based placeholder text; re-fetch after Phase 2 completes to see the enriched values.

Copy-paste walkthrough

Set your environment first:

export API_KEY="galya_..."
export USER_ID="shopper_jordan"
export BASE="https://api.galya.io/v1"

1. Create the user

curl -sS -X POST "$BASE/entity" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "'"$USER_ID"'",
    "type": "user",
    "name": "Jordan",
    "description": "Coastal minimalist."
  }'

Response 200:

{
  "id": "shopper_jordan",
  "entity_id": "shopper_jordan",
  "name": "Jordan",
  "description": "Coastal minimalist.",
  "type": "user",
  "linked_content": [],
  "linked_entities": []
}

2. Index catalog items linked to the user

Repeat this call once per item. The entity_id here is the user you're linking the content to.

curl -sS -X POST "$BASE/index" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": {
      "url": "https://store.example/oak-credenza",
      "type": "text",
      "content": "Low oak credenza, linen front, coastal minimalist.",
      "skip_url_fetch": true
    },
    "entity_id": "'"$USER_ID"'"
  }'

Response 200:

{
  "entity_id": "a1b2c3d4e5f6...",
  "created": true
}

created is false if this URL was already indexed. The returned entity_id is the content item's new hashed id.

Index a second item so the taste has something to work with:

curl -sS -X POST "$BASE/index" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "content": {
      "url": "https://store.example/linen-chair",
      "type": "text",
      "content": "Linen lounge chair, pale oak frame, airy minimalist.",
      "skip_url_fetch": true
    },
    "entity_id": "'"$USER_ID"'"
  }'

Search the catalog for this user's taste. Both query params are required.

curl -sS -X POST "$BASE/search?relative_to_entity_id=$USER_ID&in_terms_of_entity_type=content" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "calm coastal furniture in natural materials"
  }'

Response 200, best match first:

{
  "results": [
    {
      "id": "a1b2c3d4e5f6...",
      "name": "Oak credenza",
      "description": "Low oak credenza, linen front, coastal minimalist.",
      "type": "content",
      "linked_content": [],
      "linked_entities": []
    }
  ]
}

4. Rerank your own shortlist

Send Galya the candidates you already have — inline content, { entity_id } refs, or a mix — and it returns them reordered for the user's taste. No taste profile needed if you only rerank against the anchor's own indexed content.

curl -sS -X POST "$BASE/rerank?relative_to_entity_id=$USER_ID&in_terms_of_entity_type=content" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "candidates": [
      {
        "url": "https://store.example/walnut-desk",
        "type": "text",
        "content": "Glossy walnut executive desk, ornate, maximalist."
      },
      {
        "url": "https://store.example/linen-chair",
        "type": "text",
        "content": "Linen lounge chair, pale oak frame, airy minimalist."
      }
    ]
  }'

Response 200, best match first:

{
  "results": [
    {
      "id": "…",
      "name": "Linen lounge chair",
      "description": "Linen lounge chair, pale oak frame, airy minimalist.",
      "type": "content",
      "linked_content": [],
      "linked_entities": []
    },
    {
      "id": "…",
      "name": "Walnut executive desk",
      "description": "Glossy walnut executive desk, ornate, maximalist.",
      "type": "content",
      "linked_content": [],
      "linked_entities": []
    }
  ]
}

Coming soon

Recommend (top-k for a user by id) — coming soon

A single call that returns the top-k best matches for a user id, with no query and no candidate list. Today, use POST /v1/search with a broad query or POST /v1/rerank over a candidate pool you control.

Browser SDK auto-instrumentation — coming soon

The browser SDK will auto-instrument POST /v1/entity and POST /v1/index from the client. Link to the SDK docs will land here when it ships.

MCP server — coming soon

An MCP server exposing these endpoints to tool-using agents is planned.

On this page