TypeDB HTTP API
If the server is part of a cluster, see Clustered servers for how requests reach the primary.
Authorization
Sign in
Request an API token to authenticate against the rest of the API using user credentials.
This token must be used as ACCESS_TOKEN for other protected methods.
Token required |
No |
|---|---|
Method |
|
URL |
|
Request body |
|
Request headers |
None |
Responses:
200: OK
{
"token": string
}
400: Bad Request
Possible causes:
-
Incorrectly formatted request
Response format:
{
"code": string,
"message": string
}
401: Unauthorized
Possible causes:
-
Invalid credentials
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request POST \
--url http://localhost:8000/v1/signin \
--json '{"username": "USERNAME", "password": "PASSWORD"}'
import requests
url = "http://localhost:8000/v1/signin"
body = {
"username": "USERNAME",
"password": "PASSWORD"
}
response = requests.post(url, json=body)
use reqwest;
use serde::Serialize;
#[derive(Serialize)]
struct Signin {
username: String,
password: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let signin = Signin {
username: "username".to_string(),
password: "password".to_string(),
};
let client = reqwest::Client::new();
let resp = client
.post("http://localhost:8000/v1/signin")
.json(&signin)
.send().await;
Ok(())
}
Example response:
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6MTc0NDYzNTI5NSwiaWF0IjoxNzQ0NjIwODk1fQ.WEhmBTAXI_qZUlAB7zw52LDGJhnqfNTXS63QDSZlqds"
}
Server information
Version
Get the server’s distribution and version information.
Token required |
No |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
None |
Responses:
200: OK
{
"distribution": string,
"version": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request GET \
--url http://localhost:8000/v1/version
import requests
url = "http://localhost:8000/v1/version"
response = requests.get(url)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.get("http://localhost:8000/v1/version")
.send().await;
Ok(())
}
Example response:
{
"distribution": "TypeDB",
"version": "3.2.0"
}
Databases
Get databases
Get all databases present on the server.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
{
"databases": [
{
"name": string
}
]
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request GET \
--url http://localhost:8000/v1/databases \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/databases"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.get(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.get("http://localhost:8000/v1/databases")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Get database
Get a single database present on the server by name.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
{
"name": string
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request GET \
--url http://localhost:8000/v1/databases/DATABASE_NAME \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/databases/DATABASE_NAME"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.get(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.get("http://localhost:8000/v1/databases/DATABASE_NAME")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Create database
Create a database on the server.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
No body.
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request POST \
--url http://localhost:8000/v1/databases/DATABASE_NAME \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/databases/DATABASE_NAME"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.post(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.post("http://localhost:8000/v1/databases/DATABASE_NAME")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Delete database
Delete a database from the server by name.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
No body.
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request DELETE \
--url http://localhost:8000/v1/databases/DATABASE_NAME \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/databases/DATABASE_NAME"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.delete(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.delete("http://localhost:8000/v1/databases/DATABASE_NAME")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Get database’s schema
Retrieve a full schema text as a valid TypeQL define query string. This includes function definitions.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
"define <statements>;"
""
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request GET \
--url http://localhost:8000/v1/databases/DATABASE_NAME/schema \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/databases/DATABASE_NAME/schema"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.get(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.get("http://localhost:8000/v1/databases/DATABASE_NAME/schema")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Get database’s type schema
Retrieve the types in the schema as a valid TypeQL define query string.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
"define <statements>;"
""
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request GET \
--url http://localhost:8000/v1/databases/DATABASE_NAME/type-schema \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/databases/DATABASE_NAME/type-schema"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.get(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.get("http://localhost:8000/v1/databases/DATABASE_NAME/type-schema")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Users
Get users
Get all users present on the server.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
{
"users": [
{
"username": string
}
]
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request GET \
--url http://localhost:8000/v1/users \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/users"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.get(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.get("http://localhost:8000/v1/users")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Get user
Get a single user present on the server by name.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
{
"username": string
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request GET \
--url http://localhost:8000/v1/users/USERNAME \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/users/USERNAME"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.get(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.get("http://localhost:8000/v1/users/USERNAME")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Create user
Create a new user on the server.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
|
Request headers |
|
Responses:
200: OK
No body.
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request POST \
--url http://localhost:8000/v1/users/USERNAME \
--header 'Authorization: Bearer {ACCESS-TOKEN}' \
--json '{"password": "PASSWORD"}'
import requests
url = "http://localhost:8000/v1/users/USERNAME"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
body = {
"password": "PASSWORD"
}
response = requests.post(url, headers=headers, json=body)
use reqwest;
use serde::Serialize;
#[derive(Serialize)]
struct UserCredentials {
password: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let user_credentials = UserCredentials {
password: "password".to_string(),
};
let client = reqwest::Client::new();
let resp = client
.post("http://localhost:8000/v1/users/USERNAME")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.json(&user_credentials)
.send().await;
Ok(())
}
Update user
Update credentials for a user present on the server.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
|
Request headers |
|
Responses:
200: OK
No body.
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request PUT \
--url http://localhost:8000/v1/users/USERNAME \
--header 'Authorization: Bearer {ACCESS-TOKEN}' \
--json '{"password": "PASSWORD"}'
import requests
url = "http://localhost:8000/v1/users/USERNAME"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
body = {
"password": "PASSWORD"
}
response = requests.put(url, headers=headers, json=body)
use reqwest;
use serde::Serialize;
#[derive(Serialize)]
struct UserCredentials {
password: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let user_credentials = UserCredentials {
password: "password".to_string(),
};
let client = reqwest::Client::new();
let resp = client
.put("http://localhost:8000/v1/users/USERNAME")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.json(&user_credentials)
.send().await;
Ok(())
}
Delete user
Delete a user from the server by name.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
No body.
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
401: Unauthorized
Possible causes:
-
Invalid token
-
Expired token
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request DELETE \
--url http://localhost:8000/v1/users/USERNAME \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/users/USERNAME"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.delete(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.delete("http://localhost:8000/v1/users/USERNAME")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Transactions
Open transaction
Open a new transaction and receive a unique transaction id.
Use the weakest transaction type that fits your operation (read < write < schema): schema transactions are exclusive and block all other write and schema transactions from opening while they are open.
|
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
|
Request headers |
|
Transaction options:
| Field | Description |
|---|---|
|
The maximum amount of time a transaction can stay opened. It will be closed automatically without preserving its changes and finishing its active queries after this timeout. Specified in milliseconds. Default: 5 minutes |
|
Timeout for a schema transaction to acquire the exclusive schema lock of the database. Can be used to wait until a previous schema transaction finishes and releases the exclusivity lock. Specified in milliseconds. Default: 10 seconds |
Responses:
200: OK
{
"transactionId": string
}
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request POST \
--url http://localhost:8000/v1/transactions/open \
--header 'Authorization: Bearer {ACCESS-TOKEN}' \
--json '{"databaseName": "DATABASE_NAME", "transactionType": "schema"}'
import requests
url = "http://localhost:8000/v1/transactions/open"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
body = {
"databaseName": "DATABASE_NAME",
"transactionType": "schema",
}
response = requests.post(url, headers=headers, json=body)
use reqwest;
use serde::Serialize;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub enum TransactionType {
Read,
Write,
Schema,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct Transaction {
database_name: String,
transaction_type: TransactionType,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let transaction = Transaction {
database_name: DATABASE_NAME,
transaction_type: TransactionType::Schema,
};
let client = reqwest::Client::new();
let resp = client
.post("http://localhost:8000/v1/transactions/open")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.json(&transaction)
.send().await;
Ok(())
}
Close transaction
Close a transaction without preserving its changes by transaction id.
This operation is idempotent: closing a transaction that is already closed (or was never opened) succeeds with an empty 200 response.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
No body.
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request POST \
--url http://localhost:8000/v1/transactions/TRANSACTION_ID/close \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/transactions/TRANSACTION_ID/close"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.post(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.post("http://localhost:8000/v1/transactions/TRANSACTION_ID/close")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Commit transaction
Commit and close a transaction, preserving it changes on the server.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
No body.
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request POST \
--url http://localhost:8000/v1/transactions/TRANSACTION_ID/commit \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/transactions/TRANSACTION_ID/commit"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.post(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.post("http://localhost:8000/v1/transactions/TRANSACTION_ID/commit")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Rollback transaction
Rolls back the uncommitted changes made via a transaction. The transaction remains open afterwards and can accept further queries. To dispose of a transaction without committing, use close instead.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
|
Responses:
200: OK
No body.
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request POST \
--url http://localhost:8000/v1/transactions/TRANSACTION_ID/rollback \
--header 'Authorization: Bearer {ACCESS-TOKEN}'
import requests
url = "http://localhost:8000/v1/transactions/TRANSACTION_ID/rollback"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
response = requests.post(url, headers=headers)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.post("http://localhost:8000/v1/transactions/TRANSACTION_ID/rollback")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.send().await;
Ok(())
}
Query in transaction
Run a query within an open transaction. This endpoint allows running multiple sequential queries before committing.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
|
Request headers |
|
Query options:
| Field | Description |
|---|---|
|
Whether to include the types of the returned instance concepts in concept row responses or not. This option allows reducing the amount of unnecessary data transmitted. Default: true |
|
The maximum allowed size of concept rows or concept documents answers returned. Used to limit the network load. At most count limit answers is returned.
If it is a write query, all changes, including both returned and not returned, will be applied.
If there are more answers cut, a relevant Default: 10 000 |
|
Whether to include a structural analysis of the query in the The analysis adds a constant overhead (typically under 1 KB) to every response, independent of the number of answers returned.
Set this option to Default: true |
Given rows:
Each given row maps a 'given' variable to an instance or value. For write queries, passing many given rows to a single query is the most efficient way to bulk-load data: the query is parsed and planned once and executed for all rows. .Examples:
Details
{
"query": "given $p: person, $n: string, $dob: datetime-tz;\ninsert $p has name == $n, has date-of-birth == $dob;",
"given": [
{
"p": {
"kind": "entity",
"iid": "0x1e00000000000000000001"
},
"n": {
"kind": "value",
"valueType": "string",
"value": "John"
},
"dob": "1987-12-22T17:29 Asia/Kolkata"
}
]
}
Responses:
200: OK
{
"queryType": "read" | "write" | "schema",
"answerType": "ok" | "conceptRows" | "conceptDocuments",
"answers": [ ... ], // optional
"query": { ... }, // optional: structural analysis of the query, controlled by the includeQueryStructure query option
"warning": string // optional
}
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
408: Request Timeout
Possible causes:
-
Request finished with an error due to an execution timeout
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request POST \
--url http://localhost:8000/v1/transactions/TRANSACTION_ID/query \
--header 'Authorization: Bearer {ACCESS-TOKEN}' \
--json '{"query": "define entity person;"}'
import requests
url = "http://localhost:8000/v1/transactions/TRANSACTION_ID/query"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
body = {
"query": "define entity person;"
}
response = requests.post(url, headers=headers, json=body)
use reqwest;
use serde::Serialize;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct Query {
query: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let query = Query {
query: "define entity person;".to_string(),
};
let client = reqwest::Client::new();
let resp = client
.post("http://localhost:8000/v1/transactions/TRANSACTION_ID/query")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.json(&query)
.send().await;
Ok(())
}
Example responses for each concept:
Concept rows
Request body
{
"query": "match $entity isa $entity-type, has $attribute-type $attribute; $relation isa $relation-type, links ($entity); $relation-type relates $role-type; let $value = $attribute;",
"queryOptions": {
"includeInstanceTypes": true
}
}
{
"queryType": "read",
"answerType": "conceptRows",
"answers": [
{
"data": {
"entity": {
"kind": "entity",
"iid": "0x1e00000000000000000001",
"type": {
"kind": "entityType",
"label": "person"
}
},
"role-type": {
"kind": "roleType",
"label": "parentship:parent"
},
"relation": {
"kind": "relation",
"iid": "0x1f00000000000000000000",
"type": {
"kind": "relationType",
"label": "parentship"
}
},
"relation-type": {
"kind": "relationType",
"label": "parentship"
},
"attribute-type": {
"kind": "attributeType",
"label": "name",
"valueType": "string"
},
"entity-type": {
"kind": "entityType",
"label": "person"
},
"value": {
"kind": "value",
"value": "John",
"valueType": "string"
},
"attribute": {
"kind": "attribute",
"value": "John",
"valueType": "string",
"type": {
"kind": "attributeType",
"label": "name",
"valueType": "string"
}
}
}
}
],
"warning": null
}
Concept documents
Request body
{
"query": "match $entity isa $entity-type, has $attribute-type $attribute; $relation isa $relation-type, links ($entity); $relation-type relates $role-type; fetch { 'entity type': $entity-type, 'relation type': $relation-type, 'entity attributes': { $entity.* }, 'sub query': [ match let $value = $attribute; fetch { 'value': $value }; ] };"
}
{
"queryType": "read",
"answerType": "conceptDocuments",
"answers": [
{
"entity attributes": {
"name": "John"
},
"sub query": [
{
"value": "John"
}
],
"entity type": {
"kind": "entity",
"label": "person"
},
"relation type": {
"kind": "relation",
"label": "parentship"
}
}
],
"warning": null
}
Analyze query in transaction
Analyzes a query within an open transaction, without executing it. The query is parsed and type-checked against the schema, and the response is a type-annotated structural representation of the query. See Analyzing queries for an overview of the concepts involved and the envisioned uses.
Only query pipelines can be analyzed: passing a schema query (define, undefine, or redefine) returns a 400 error.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
|
Request headers |
|
Responses:
200: OK
{
"source": string, // the analyzed query text
"query": Pipeline, // the analyzed query pipeline: conjunctions, stages, variables, outputs
"preamble": Function[], // analyzed preamble functions ('with fun ...')
"given": Given, // optional: input variables and their annotations, if the query has a 'given' stage
"fetch": Fetch // optional: possible fields of the fetch result, if the query has a 'fetch' stage
}
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
408: Request Timeout
Possible causes:
-
Request finished with an error due to an execution timeout
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request POST \
--url http://localhost:8000/v1/transactions/TRANSACTION_ID/analyze \
--header 'Authorization: Bearer {ACCESS-TOKEN}' \
--json '{"query": "match $person isa person, has name $name;"}'
import requests
url = "http://localhost:8000/v1/transactions/TRANSACTION_ID/analyze"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
body = {
"query": "match $person isa person, has name $name;"
}
response = requests.post(url, headers=headers, json=body)
use reqwest;
use serde::Serialize;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct Analyze {
query: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let analyze = Analyze {
query: "match $person isa person, has name $name;".to_string(),
};
let client = reqwest::Client::new();
let resp = client
.post("http://localhost:8000/v1/transactions/TRANSACTION_ID/analyze")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.json(&analyze)
.send().await;
Ok(())
}
Example response:
Analyzed query
{
"source": "match $person isa person, has name $name;",
"given": null,
"query": {
"conjunctions": [
{
"constraints": [
{
"textSpan": {
"begin": 14,
"end": 24
},
"tag": "isa",
"instance": {
"tag": "variable",
"id": "0"
},
"type": {
"tag": "label",
"type": {
"kind": "entityType",
"label": "person"
}
}
},
{
"textSpan": {
"begin": 26,
"end": 40
},
"tag": "has",
"owner": {
"tag": "variable",
"id": "0"
},
"attribute": {
"tag": "variable",
"id": "1"
}
},
{
"textSpan": {
"begin": 30,
"end": 34
},
"tag": "isa",
"instance": {
"tag": "variable",
"id": "1"
},
"type": {
"tag": "label",
"type": {
"kind": "attributeType",
"label": "name",
"valueType": "string"
}
}
}
],
"annotations": {
"variableAnnotations": {
"1": {
"isOptional": false,
"tag": "instance",
"annotations": [
{
"kind": "attributeType",
"label": "name",
"valueType": "string"
}
]
},
"0": {
"isOptional": false,
"tag": "instance",
"annotations": [
{
"kind": "entityType",
"label": "person"
}
]
}
}
}
}
],
"stages": [
{
"tag": "match",
"block": 0
}
],
"variables": {
"1": {
"name": "name"
},
"0": {
"name": "person"
}
},
"outputs": [
"0",
"1"
]
},
"preamble": [],
"fetch": null
}
One-shot query
Run a one-shot query. This endpoint executes a query within a temporary transaction that is opened and then either committed or closed exclusively for this query.
Token required |
Yes |
|---|---|
Method |
|
URL |
|
Request body |
|
Request headers |
|
Transaction options:
| Field | Description |
|---|---|
|
The maximum amount of time a transaction can stay opened. It will be closed automatically without preserving its changes and finishing its active queries after this timeout. Specified in milliseconds. Default: 5 minutes |
|
Timeout for a schema transaction to acquire the exclusive schema lock of the database. Can be used to wait until a previous schema transaction finishes and releases the exclusivity lock. Specified in milliseconds. Default: 10 seconds |
Query options:
| Field | Description |
|---|---|
|
Whether to include the types of the returned instance concepts in concept row responses or not. This option allows reducing the amount of unnecessary data transmitted. Default: true |
|
The maximum allowed size of concept rows or concept documents answers returned. Used to limit the network load. At most count limit answers is returned.
If it is a write query, all changes, including both returned and not returned, will be applied.
If there are more answers cut, a relevant Default: 10 000 |
|
Whether to include a structural analysis of the query in the The analysis adds a constant overhead (typically under 1 KB) to every response, independent of the number of answers returned.
Set this option to Default: true |
Responses:
200: OK
{
"queryType": "read" | "write" | "schema",
"answerType": "ok" | "conceptRows" | "conceptDocuments",
"answers": [ ... ], // optional
"query": { ... }, // optional: structural analysis of the query, controlled by the includeQueryStructure query option
"warning": string // optional
}
400: Bad Request
Possible causes:
-
Incorrectly formatted request (e.g. Authorization header missing a token)
Response format:
{
"code": string,
"message": string
}
403: Forbidden
Possible causes:
-
The supplied access token lacks the required access level for the request
Response format:
{
"code": string,
"message": string
}
404: Not Found
Possible causes:
-
One or more resources referenced in the request could not be found
Response format:
{
"code": string,
"message": string
}
408: Request Timeout
Possible causes:
-
Request finished with an error due to an execution timeout
Response format:
{
"code": string,
"message": string
}
Example request:
-
curl
-
Python
-
Rust
curl --request POST \
--url http://localhost:8000/v1/query \
--header 'Authorization: Bearer {ACCESS-TOKEN}' \
--json '{"databaseName": "DATABASE_NAME", "transactionType": "schema", "query": "define entity person;"}'
import requests
url = "http://localhost:8000/v1/query"
headers = {
"Authorization": "Bearer {ACCESS-TOKEN}"
}
body = {
"databaseName": "DATABASE_NAME",
"transactionType": "schema",
"query": "define entity person;"
}
response = requests.post(url, headers=headers, json=body)
use reqwest;
use serde::Serialize;
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub enum TransactionType {
Read,
Write,
Schema,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct OneshotQuery {
database_name: String,
transaction_type: TransactionType,
query: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let query = OneshotQuery {
database_name: DATABASE_NAME,
transaction_type: TransactionType::Schema,
query: "define entity person;".to_string(),
};
let client = reqwest::Client::new();
let resp = client
.post("http://localhost:8000/v1/query")
.header(reqwest::header::AUTHORIZATION, "Bearer {ACCESS-TOKEN}")
.json(&query)
.send().await;
Ok(())
}
Example responses for each concept:
Concept rows
Request body
{
"databaseName": "test",
"transactionType": "read",
"query": "match $entity isa $entity-type, has $attribute-type $attribute; $relation isa $relation-type, links ($entity); $relation-type relates $role-type; let $value = $attribute;",
"queryOptions": {
"includeInstanceTypes": true
}
}
{
"queryType": "read",
"answerType": "conceptRows",
"answers": [
{
"data": {
"entity": {
"kind": "entity",
"iid": "0x1e00000000000000000001",
"type": {
"kind": "entityType",
"label": "person"
}
},
"role-type": {
"kind": "roleType",
"label": "parentship:parent"
},
"relation": {
"kind": "relation",
"iid": "0x1f00000000000000000000",
"type": {
"kind": "relationType",
"label": "parentship"
}
},
"relation-type": {
"kind": "relationType",
"label": "parentship"
},
"attribute-type": {
"kind": "attributeType",
"label": "name",
"valueType": "string"
},
"entity-type": {
"kind": "entityType",
"label": "person"
},
"value": {
"kind": "value",
"value": "John",
"valueType": "string"
},
"attribute": {
"kind": "attribute",
"value": "John",
"valueType": "string",
"type": {
"kind": "attributeType",
"label": "name",
"valueType": "string"
}
}
}
}
],
"warning": null
}
Concept documents
Request body
{
"databaseName": "test",
"transactionType": "read",
"query": "match $entity isa $entity-type, has $attribute-type $attribute; $relation isa $relation-type, links ($entity); $relation-type relates $role-type; fetch { 'entity type': $entity-type, 'relation type': $relation-type, 'entity attributes': { $entity.* }, 'sub query': [ match let $value = $attribute; fetch { 'value': $value }; ] };"
}
{
"queryType": "read",
"answerType": "conceptDocuments",
"answers": [
{
"entity attributes": {
"name": "John"
},
"sub query": [
{
"value": "John"
}
],
"entity type": {
"kind": "entity",
"label": "person"
},
"relation type": {
"kind": "relation",
"label": "parentship"
}
}
],
"warning": null
}
Health check
Check that the server is accessible and healthy.
Token required |
No |
|---|---|
Method |
|
URL |
|
Request body |
None |
Request headers |
None |
Responses:
204: No Content
No body.
Example request:
-
curl
-
Python
-
Rust
curl --request GET \
--url http://localhost:8000/health
import requests
url = "http://localhost:8000/health"
response = requests.get(url)
use reqwest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let resp = client
.get("http://localhost:8000/health")
.send().await;
Ok(())
}
Clustered servers
In a cluster, an HTTP client talks to one server at a time.
Any server answers sign-in, version, and health requests.
A database, user, transaction, or query request that reaches a secondary is answered with 421 Misdirected Request and a JSON body whose primaryAddress is the primary’s HTTP advertise address (server.http.advertise-address), or with 503 Service Unavailable while no primary is known.
Sign in again at that address and retry: a token is only valid on the server that issued it.
The TypeScript HTTP driver does this automatically.
When the HTTP advertise addresses are not reachable from the client, give it translatedAddresses instead of addresses: for every replica, the address the client reaches it at (external) and its HTTP advertise address (internal), as described in How clients reach the replicas.
const driver = new TypeDBHttpDriver({
username: "admin",
password: "password",
translatedAddresses: [
{ external: "https://typedb-1.example.com:8000", internal: "https://10.0.0.1:8000" },
{ external: "https://typedb-2.example.com:8000", internal: "https://10.0.0.2:8000" },
{ external: "https://typedb-3.example.com:8000", internal: "https://10.0.0.3:8000" },
],
});