GraphQL
The GraphQL API allows you to query and manipulate your database data using a dynamically generated schema. Each table in your schema is automatically mapped to GraphQL types, queries, and mutations.
Endpoint and Authentication
The GraphQL endpoint is schema-specific (see Schemas for more information):
POST https://api.centia.io/api/graphql/schema/{schema_name}
Authentication is handled via a Bearer token in the Authorization header (see OAuth for more information).
POST https://api.centia.io/api/graphql/schema/public
Authorization: Bearer <your_token>
Content-Type: application/json
{
"query": "query { ... }"
}
The GraphQL API can currently only be used in http context. Websockets will be supported soon.
Introspection
You can use standard GraphQL introspection to explore the available types and fields. This is useful for tools like GraphiQL or Apollo Studio.
query {
__schema {
types {
name
}
}
}
Queries
For every table in your database, the API provides a query field named get[TableName] (in camelCase).
Basic Query
To fetch records from a table named artists:
POST https://api.centia.io/api/graphql/schema/public
Content-Type: application/json
Authorization: Bearer <your_token>
{
"query": "query { getArtists { artist_id legal_name } }"
}
Filtering
The where argument supports complex filtering using logical and comparison operators. Simple equality filters are also supported.
Simple Equality:
{ getArtists(where: { artist_id: 1 }) { legal_name } }
Supported Operators:
eq: Equalneq: Not equalgt: Greater thangte: Greater than or equallt: Less thanlte: Less than or equalin: Included in arraylike: Case-sensitive pattern matchilike: Case-insensitive pattern match
Logical Operators:
and: Logical ANDor: Logical ORnot: Logical NOT
POST https://api.centia.io/api/graphql/schema/public
Content-Type: application/json
Authorization: Bearer <your_token>
{
"query": "query { getArtists(where: { and: [ { legal_name: { ilike: \"%Linus%\" } }, { instrument: { eq: \"guitar\" } } ] }) { legal_name instrument } }"
}
Pagination
Use limit and offset for pagination.
POST https://api.centia.io/api/graphql/schema/public
Content-Type: application/json
Authorization: Bearer <your_token>
{
"query": "query { getArtists(limit: 10, offset: 20) { artist_id legal_name } }"
}
Relationships
If there are foreign key constraints between tables, the GraphQL API automatically exposes them as nested fields.
POST https://api.centia.io/api/graphql/schema/public
Content-Type: application/json
Authorization: Bearer <your_token>
{
"query": "query { getAlbums { title bands { name subgenre } } }"
}
Mutations
The API provides insert, update, and delete mutations for each table.
Insert
Use insert[TableName] to add new records. You can provide a single record via data or multiple records via objects.
POST https://api.centia.io/api/graphql/schema/public
Content-Type: application/json
Authorization: Bearer <your_token>
{
"query": "mutation { insertArtists(objects: [{ legal_name: \"John Doe\", instrument: \"Piano\" }]) { artist_id legal_name } }"
}
Update
Use update[TableName] to modify existing records. Use the where argument to specify which records to update and data for the new values.
POST https://api.centia.io/api/graphql/schema/public
Content-Type: application/json
Authorization: Bearer <your_token>
{
"query": "mutation { updateArtists(where: { artist_id: { eq: 1 } }, data: { instrument: \"Electric Guitar\" }) { artist_id instrument } }"
}
Delete
Use delete[TableName] to remove records.
POST https://api.centia.io/api/graphql/schema/public
Content-Type: application/json
Authorization: Bearer <your_token>
{
"query": "mutation { deleteArtists(where: { artist_id: { eq: 1 } }) { artist_id } }"
}
Data Types
The GraphQL API supports various PostgreSQL data types, mapping them to appropriate GraphQL types:
- Scalars:
integer,float,boolean,string,JSON,ID,Date,Time,DateTime. - Geometric Types:
Point,Line,Lseg,Box,Circle,Path,Polygon. - Range Types:
Int4range,Int8range,Numrange,Tsrange,Tstzrange,Daterange. - Arrays: Any type can be returned as a list (e.g.,
[String],[Int]).
Any complex types can be used as input arguments for mutations. Type hints are not required because the schemas are dynamically generated from the database relations.
Se also Types.
Consider a generated schema like this:
type Tours {
id: ID!
artist_name: String!
tour_name: String!
from_to: Daterange!
}
"""
Date is accepted in almost any reasonable format, including ISO 8601, SQL-compatible, traditional POSTGRES, and others.
"""
scalar Date
"""Range type for daterange, with lower and upper bounds of type Date."""
type Daterange {
lower: Date
upper: Date
lowerInclusive: Boolean
upperInclusive: Boolean
}
type Mutation {
insertTours(data: JSON, objects: [JSON]): [Tours]
updateTours(id: ID, where: JSON, data: JSON): [Tours]
deleteTours(id: ID, where: JSON): [Tours]
}
Then you can insert a new tour using the following mutation. The Daterange field is represented as JSON:
mutation InsertTours($data: JSON) {
insertTours(data: $data) {
id
from_to {
lower
upper
}
}
}
{
"data": {
"artist_name": "Guns n’ Roses",
"tour_name": "Europe: Summer 2026",
"from_to": {
"lower": "2010-04-06",
"upper": "2011-03-07",
"lowerInclusive": true,
"upperInclusive": true
}
}
}