Docs · GraphQL API

GraphQL API

Two kinds of thing exist in Closure. Everything else is a projection.

DataSchemaDataObject
JobDeclares a shapeIs a row of that shape
Identityschema:…urn:uuid:…
Exampleschema:experience, schema:workflow, schema:pageCRM Lite Experience, a lead-capture workflow, a page
JSON-LD is how objects carry meaning. GraphQL is how you query and mutate the store.

Same store the console, Experiences, Knowledge → Data, and your IDE all use. Auth: Closure session (POST /api/graphql). GET /api/graphql returns the SDL.

Browser apps should call your BFF, which proxies with org credentials — see SDK & client.


Mental model

DataSchema  ──types──▶  DataObject store (G)
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
         GraphQL         Renderer         Runtime
         (query)       (Experiences)    (Workflows API)

A page is a DataObject. A component is a DataObject. A workflow graph is a DataObject. A skill is a DataObject. One type in GraphQL (DataObject); schemaRef differentiates meaning.

Paradigm deep-dive: Everything is JSON-LD · why this model: Why a Product Graph?


Try it here

Don't read about it — query it. The playground below runs the real Platform GraphQL executor against an in-memory sample org (org_demo) — same SDL as production. No session required. Everything on the rest of this page can be pasted straight in.

For your live Organization: Closure → Knowledge → Data → GraphQL.


Live sample · org_demo

Real Platform GraphQL executor · 4 seeded DataObjects

// Result appears here

Sample DataObject (JSON-LD)

What lands in the store — and what GraphQL returns under data:

{
  "@context": "https://closureapps.com/schema/context.jsonld",
  "@id": "urn:uuid:16e43167-66ad-5e94-a0e8-60f9d482fcfe",
  "schemaRef": "schema:experience",
  "name": "Demo Experience",
  "orgId": "org_demo",
  "state": "active",
  "data": {
    "slug": "demo",
    "homePath": "/",
    "homePageId": "urn:uuid:720eedf1-10a6-5030-a53d-9f6b2e57fd82",
    "pageIds": ["urn:uuid:720eedf1-10a6-5030-a53d-9f6b2e57fd82"],
    "nav": [{ "label": "Home", "href": "/" }]
  }
}

A DataSchema row (schemaRef: "schema:data_schema") describes fields other objects must carry — meta-schema, same store.


Schema (SDL)

type DataObject {
  id: ID!
  orgId: String!
  schemaRef: String!
  name: String!
  state: String!
  data: JSON!
  links: JSON
  createdAt: String!
  updatedAt: String!
}

type Query {
  object(id: ID!): DataObject
  objects(orgId: String!, schemaRef: String, where: ObjectWhere, limit: Int): [DataObject!]!
  experience(orgId: String!, slug: String!): DataObject
  resolveBind(orgId: String!, bind: JSON!): JSON!
}

type Mutation {
  upsertObject(input: UpsertObjectInput!): DataObject!
  deleteObject(id: ID!): Boolean!
}

orgId can be omitted when the session already scopes the Organization.


Cookbook

List Experiences

query {
  objects(orgId: "org_demo", schemaRef: "schema:experience", limit: 50) {
    id
    name
    state
    data
    updatedAt
  }
}

Resolve by slug

query {
  experience(orgId: "org_demo", slug: "demo") {
    id
    name
    data
  }
}

Follow the graph (page → components)

query {
  objects(orgId: "org_demo", schemaRef: "schema:page", limit: 20) {
    id
    name
    data
  }
}

Then query schema:component and match data / links to the page’s rootComponentId.

Upsert

mutation ($input: UpsertObjectInput!) {
  upsertObject(input: $input) {
    id
    updatedAt
  }
}
{
  "input": {
    "id": "urn:uuid:aaaaaaaa-aaaa-5aaa-8aaa-aaaaaaaaaaaa",
    "orgId": "org_demo",
    "schemaRef": "schema:artifact",
    "name": "Signal",
    "data": { "kind": "note", "title": "Hello graph" }
  }
}

Curl

curl -sS https://closureapps.com/console/api/graphql \
  -H "Content-Type: application/json" \
  -H "Cookie: <your-session>" \
  -d '{"query":"query { objects(orgId: \"org_demo\", schemaRef: \"schema:experience\", limit: 5) { id name } }"}'

Boundaries

Do with GraphQLDo with Workflows API
Read / write DataObjectsStart and advance runs
Bind Experiences (resolveBind)Collect → agent → HITL → seal
Inspect schema:workflow rowsExecute the process graph

Workflow execution: Workflows API.

What is not (yet)

  • Public API-key multi-tenant GraphQL for anonymous internet clients — roadmap
  • L1’s richer executeFunction / executeWorkflow GraphQL surface — Platform keeps execution on the Workflows HTTP API on purpose