Metadata API Reference (v1.4 and above)

Introduction

This is primarily intended to be used as an admin API to manage the Hasura metadata.

Endpoint

All requests are POST requests to the /v1/metadata endpoint.

Request structure

POST /v1/metadata HTTP/1.1

{
   "type": <query-type>,
   "version": <Integer> (optional),
   "args": <args-object>
}

The structure of args depends on the type and version.

Request body

Query

Query

Key Required Schema Description
type true String Type of the query
args true JSON Value The arguments to the query
version false Integer Version of the API (inferred by args structure)

Request types

The various types of queries are listed in the following table:

type args version Synopsis
bulk Query array 1 Execute multiple operations in a single query
pg_create_function_permission pg_create_function_permission_args 1 Create a function permission
pg_drop_function_permission pg_drop_function_permission_args 1 Drop an existing function permission
replace_metadata Args syntax 1 Drop an existing function permission

Response structure

Status code Description Response structure
200 Success
Request specific
400 Bad request
{
    "path"  : String,
    "error" : String
}
401 Unauthorized
{
    "error" : String
}
500 Internal server error
{
    "error" : String
}

Disabling metadata API

Since this API can be used to make changes to the GraphQL schema, it can be disabled, especially in production deployments.

The enabled-apis flag or the HASURA_GRAPHQL_ENABLED_APIS env var can be used to enable/disable this API. By default, the schema/metadata API is enabled. To disable it, you need to explicitly state that this API is not enabled i.e. remove it from the list of enabled APIs.

# enable only graphql api, disable metadata and pgdump
--enabled-apis="graphql"
HASURA_GRAPHQL_ENABLED_APIS="graphql"

See GraphQL engine server flags reference for info on setting the above flag/env var.

Error codes

Status Code Code Error
400 postgres-error Not-NULL violation. null value in column <column-name> violates not-null constraint
400 permission-denied select on <column/table> for role <role-name> is not allowed.
400 not-exists table <table-name> does not exist
400 not-exists no such table/view exists in postgres : <table-name>
400 not-exists <field-name> does not exist
400 already-tracked view/table already tracked : <table-name>
400 access-denied restricted access : admin only
400 not-supported table renames are not yet supported : <table-name>
400 not-exists <column-name> does not exist
400 already-exists cannot add column <column-name> in table <table-name> as a relationship with the name already exists
400 invalid-json invalid json
400 not-supported column renames are not yet supported : <table-name>.<column-name>
400 invalid-headers missing header : <header-name>
400 dependency-error cannot change type of column <column-name> in table <table-name> because of the following dependencies : <dependencies>
400 invalid-headers X-Hasura-User-Id should be an integer
400 dependency-error cannot drop due to the following dependent objects : <dependencies>
400 access-denied You have to be admin to access this endpoint
400 parse-failed parsing dotted table failed : <table-name>
400 access-denied not authorised to access this tx
400 already-exists multiple declarations exist for the following <table-name> : <duplicates>
400 not-exists tx does not exists
400 already-exists column/relationship of table <table-name> already exists
400 already-initialised the state seems to be initialised already. you may need to migrate from this version: <catalog-version>
400 constraint-error no foreign constraint exists on the given column
400 not-supported unsupported version : <catalog-version>
400 constraint-error more than one foreign key constraint exists on the given column
400 already-exists the query template already exists <template-name>
400 permission-error <permission-type>’ permission on <table-name> for role <role-name> already exists
400 permission-error <permission-type>’ permission on <table-name> for role <role-name> does not exist
400 unexpected-payload Unknown operator : <operator-type>
400 unexpected-payload expecting a string for column operator
400 unexpected-payload incompatible column types : ‘<column-name>’, ‘<column-name>’
400 unexpected-payload Expecting ‘constraint’ or ‘constraint_on’ when the ‘action’ is ‘update’
400 unexpected-payload constraint’ and ‘constraint_on’ cannot be set at a time
400 unexpected-payload upsert is not allowed for role ‘<role-name>’
400 unexpected-payload objects should not be empty
400 invalid-params missing parameter : <param-name>
400 unexpected-payload can’t be empty
400   <col-name>’ is a relationship and should be expanded
400 unexpected-payload <column-name>’ should be included in ‘columns’
400 unexpected-payload <column-name>’ is an array relationship and can’t be used in ‘order_by’
400   <column-name>’ is a Postgres column and cannot be chained further
400 unexpected-payload order_by array should not be empty
400 unexpected-payload when selecting an ‘obj_relationship’ ‘where’, ‘order_by’, ‘limit’ and ‘offset’ can’t be used
400 unexpected-payload atleast one of $set, $inc, $mul has to be present
400 permission-denied <permission-type> on <table-name> for role <role-name> is not allowed
400 not-exists no such column exists : <column-name>
400 permission-denied role <role-name> does not have permission to <permission-type> column <column-name>
400   expecting a postgres column; but, <name> is relationship
400 unexpected-payload JSON column can not be part of where clause
400 unexpected-payload is of type <type-name>; this operator works only on column of types <[types]>
400 postgres-error query execution failed
500 unexpected unexpected dependency of relationship : <dependency>
500 unexpected unexpected dependent object : <dependency>
500 unexpected field already exists
500 unexpected field does not exist
500 unexpected permission does not exist
500 postgres-error postgres transaction error
500 postgres-error connection error
500 postgres-error postgres query error
404 not-found No such resource exists