Galya Docs
Galya (Beta)

Operations

A compact reference card for every Beta endpoint, method, params, request, response, and common errors.

Quick lookup for the operations that work today. Base URL https://api.galya.io/v1, header X-API-Key: <key>. For the full narrative, see the Walkthrough.

Query params, not body

search, rerank, ask, and explain require relative_to_entity_id and in_terms_of_entity_type in the URL query string. Missing either returns 400 bad_request.


Create entity

POST /v1/entity: create a non-content entity (e.g. a user). Content entities come from indexing, not here.

Body: type (or legacy entity_type) and name are required; id and description are optional (a random id is generated if omitted).

curl -sS -X POST "https://api.galya.io/v1/entity" \
  -H "X-API-Key: $GALYA_API_KEY" -H "Content-Type: application/json" \
  -d '{ "id": "shopper_jordan", "type": "user", "name": "Jordan", "description": "Coastal minimalist." }'
await api.createEntity({ id: "shopper_jordan", type: "user", name: "Jordan", description: "Coastal minimalist." });

Response 200 OK:

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

Common errors:
400 "Entity requires name and type"
400 unknown entity type (register a custom type first)
401 (bad key).


Get / delete entity

GET /v1/entity?entity_id=…: fetch one entity. DELETE /v1/entity?entity_id=…: remove it.

curl -sS "https://api.galya.io/v1/entity?entity_id=shopper_jordan" -H "X-API-Key: $GALYA_API_KEY"
curl -sS -X DELETE "https://api.galya.io/v1/entity?entity_id=shopper_jordan" -H "X-API-Key: $GALYA_API_KEY"
await api.getEntity("shopper_jordan");
await api.deleteEntity("shopper_jordan"); // { success: true }

Get response 200: { id, name, description, type, linked_content, linked_entities }
Delete response 200: { "success": true }
Error: 404 "Entity not found"


Entity types

POST /v1/entity/type: register a custom type before using it on POST /entity. GET /v1/entity/type?entity_type=…: read it back. Built-in types (content, user, place, brand, website, file) need no registration.

curl -sS -X POST "https://api.galya.io/v1/entity/type" \
  -H "X-API-Key: $GALYA_API_KEY" -H "Content-Type: application/json" \
  -d '{ "entity_type": "creator" }'
await api.registerEntityType("creator");
await api.getEntityType("creator");

Response 201: { "success": true, "entity_type": "creator", "updated": false }.


Index content

POST /v1/index: index one content item (text, image, audio, video) and optionally link it to an entity. Idempotent on content.url. Indexing is synchronous and one item per call in the Beta (batch is coming soon).

Body: content (required: url, type; optional: content, skip_url_fetch, skip_media_enrich, title, description, id), entity_id (optional: links + auto-recomposes that entity).

curl -sS -X POST "https://api.galya.io/v1/index" \
  -H "X-API-Key: $GALYA_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "content": { "url": "https://store.example/oak-credenza", "type": "text", "content": "Oak credenza, linen front, coastal minimalist.", "skip_url_fetch": true },
    "entity_id": "shopper_jordan"
  }'
await api.indexContent({
  content: { url: "https://store.example/oak-credenza", type: "text", content: "Oak credenza, linen front, coastal minimalist.", skip_url_fetch: true },
  entity_id: "shopper_jordan",
});

Response 200 OK:

{ "entity_id": "a1b2c3…", "created": true }

created is false when the URL was already indexed. Errors: 400 (missing url/type, or no text to embed) · 401.


Compose

POST /v1/entity/{entity_id}/compose: build (or rebuild) a user's taste profile from their linked content. No body.

curl -sS -X POST "https://api.galya.io/v1/entity/shopper_jordan/compose" \
  -H "X-API-Key: $GALYA_API_KEY" -H "Content-Type: application/json"
const composed = await api.composeEntity("shopper_jordan");

Response 200 OK:

{ "entity_id": "shopper_jordan" }

Errors: 400 compose_no_children (no linked content yet; wait for indexing to settle and retry) · 404 (entity not found).

On slow or large indexing

Composition only sees content that has finished indexing. On slow or large catalogs, re-run compose after indexing settles. See the indexing performance note.


POST /v1/search?relative_to_entity_id=…&in_terms_of_entity_type=…: rank indexed entities of a type for an anchor's taste.

Body: query (required); additional_candidates (optional content objects ranked at query time, not persisted).

curl -sS -X POST "https://api.galya.io/v1/search?relative_to_entity_id=shopper_jordan&in_terms_of_entity_type=content" \
  -H "X-API-Key: $GALYA_API_KEY" -H "Content-Type: application/json" \
  -d '{ "query": "calm coastal furniture in natural materials" }'
const { results } = await api.search(
  { relativeToEntityId: "shopper_jordan", inTermsOfEntityType: "content" },
  { query: "calm coastal furniture in natural materials" },
);

Response 200 OK: { "results": [ { id, name, description, type, linked_content, linked_entities } ] } (best match first).
Errors: 400 (missing query params or query) · 404 (anchor not indexed).


Rerank

POST /v1/rerank?relative_to_entity_id=…&in_terms_of_entity_type=…: reorder a candidate list you provide. Works immediately, no taste history needed.

Body: candidates (required: content objects with url + type, or { entity_id } refs).

curl -sS -X POST "https://api.galya.io/v1/rerank?relative_to_entity_id=shopper_jordan&in_terms_of_entity_type=content" \
  -H "X-API-Key: $GALYA_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." }
  ] }'
const reranked = await api.rerank(
  { relativeToEntityId: "shopper_jordan", inTermsOfEntityType: "content" },
  { 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 OK: { "results": [ { id, name, description, type, linked_content, linked_entities } ] } (best match first).


Ask

POST /v1/ask?relative_to_entity_id=…&in_terms_of_entity_type=…: a natural-language answer written for the anchor's taste.

Body: query (required).

curl -sS -X POST "https://api.galya.io/v1/ask?relative_to_entity_id=shopper_jordan&in_terms_of_entity_type=content" \
  -H "X-API-Key: $GALYA_API_KEY" -H "Content-Type: application/json" \
  -d '{ "query": "Recommend a sofa and say why it fits my taste." }'
const askRes = await api.ask(
  { relativeToEntityId: "shopper_jordan", inTermsOfEntityType: "content" },
  { query: "Recommend a sofa and say why it fits my taste." },
); // cast: { answer: { content: { text: string }[] } }

Response 200 OK: { "answer": { "role": "assistant", "content": [ { "type": "text", "text": "…" } ] } }.
Errors: 400 (missing params/query) · 404 (anchor has no indexed text).


Explain

POST /v1/explain?relative_to_entity_id=…&in_terms_of_entity_type=…: grounded prose about why the anchor likes what it likes. Optional query hints: domain (discovery, design, decisions, data) and task (coding-agent, commerce-agent, design-agent, insight-agent).

Body: query (required).

curl -sS -X POST "https://api.galya.io/v1/explain?relative_to_entity_id=shopper_jordan&in_terms_of_entity_type=content&domain=design&task=design-agent" \
  -H "X-API-Key: $GALYA_API_KEY" -H "Content-Type: application/json" \
  -d '{ "query": "Summarize this shopper taste: palette, materials, silhouette." }'
const { explanation } = await api.explain(
  { relativeToEntityId: "shopper_jordan", inTermsOfEntityType: "content", domain: "design", task: "design-agent" },
  { query: "Summarize this shopper taste: palette, materials, silhouette." },
);

Response 200 OK: { "explanation": "…" }.
Errors: 400 · 404.


Clusters

GET /v1/clusters?entity_type=…&limit=…&offset=…: list taste clusters. GET /v1/cluster?cluster_id=…: fetch one.

curl -sS "https://api.galya.io/v1/clusters?entity_type=content&limit=20" -H "X-API-Key: $GALYA_API_KEY"
curl -sS "https://api.galya.io/v1/cluster?cluster_id=cl_coastal_minimal" -H "X-API-Key: $GALYA_API_KEY"
const { results } = await api.listClusters({ entityType: "content", limit: 20 });
await api.getCluster("cl_coastal_minimal");

List response 200 OK: { "results": [ { id, entity_type, clustered_entities: [] } ] } (may be empty on a new workspace).
Get error: 404 "Cluster not found".

On this page