Schema / Metadata API Reference


The schema / metadata API provides the following features:

  1. Execute SQL on the underlying Postgres database, supports schema modifying actions.
  2. Modify Hasura metadata (permission rules and relationships).

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


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

Request structure

POST /v1/query HTTP/1.1

   "type": "<query-type>",
   "args": <args-object>

Request body



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 (default: 1)

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
run_sql run_sql_args 1 Run SQL directly on Postgres
track_table TableName 1 Add a table/view
track_table track_table_args 2 Add a table/view with configuration
set_table_customization set_table_customization_args 1 Set table customization of an already tracked table
set_table_custom_fields (deprecated) set_table_custom_fields_args 2 Set custom fields of an already tracked table (deprecated)
untrack_table untrack_table_args 1 Remove a table/view
track_function FunctionName 1 Add an SQL function
track_function track_function_args 2 Add an SQL function with configuration
untrack_function FunctionName 1 Remove an SQL function
create_object_relationship create_object_relationship_args 1 Define a new object relationship
create_array_relationship create_array_relationship_args 1 Define a new array relationship
drop_relationship drop_relationship_args 1 Drop an existing relationship
rename_relationship rename_relationship_args 1 Modify name of an existing relationship
set_relationship_comment set_relationship_comment_args 1 Set comment on an existing relationship
add_computed_field add_computed_field_args 1 Add a computed field
drop_computed_field drop_computed_field_args 1 Drop a computed field
create_insert_permission create_insert_permission_args 1 Specify insert permission
drop_insert_permission drop_insert_permission_args 1 Remove existing insert permission
create_select_permission create_select_permission_args 1 Specify select permission
drop_select_permission drop_select_permission_args 1 Remove existing select permission
create_update_permission create_update_permission_args 1 Specify update permission
drop_update_permission drop_update_permission_args 1 Remove existing update permission
create_delete_permission create_delete_permission_args 1 Specify delete permission
drop_delete_permission drop_delete_permission_args 1 Remove existing delete permission
set_permission_comment set_permission_comment_args 1 Set comment on an existing permission
create_event_trigger create_event_trigger_args 1 Create or replace an event trigger
delete_event_trigger delete_event_trigger_args 1 Delete an existing event trigger
redeliver_event redeliver_event_args 1 Redeliver an existing event
invoke_event_trigger invoke_event_trigger_args 1 Invoke a trigger with custom payload
create_cron_trigger create_cron_trigger_args 1 Create a cron trigger
delete_cron_trigger delete_cron_trigger_args 1 Delete an existing cron trigger
create_scheduled_event create_scheduled_event_args 1 Create a new scheduled event
add_remote_schema add_remote_schema_args 1 Add a remote GraphQL server as a remote schema
remove_remote_schema remove_remote_schema_args 1 Remove an existing remote schema
reload_remote_schema reload_remote_schema_args 1 Reload schema of an existing remote schema
create_remote_relationship create_remote_relationship_args 1 Create a remote relationship with an existing remote schema
update_remote_relationship update_remote_relationship_args 1 Update an existing remote relationship
delete_remote_relationship delete_remote_relationship_args 1 Delete an existing remote relationship
export_metadata Empty Object 1 Export the current metadata
replace_metadata replace_metadata_args 1 Import and replace existing metadata
reload_metadata Empty Object 1 Reload changes to the underlying Postgres DB
clear_metadata Empty Object 1 Clear/wipe-out the current metadata state form server
get_inconsistent_metadata Empty Object 1 List all inconsistent metadata objects
drop_inconsistent_metadata Empty Object 1 Drop all inconsistent metadata objects
create_query_collection create_query_collection_args 1 Create a query collection
drop_query_collection drop_query_collection_args 1 Drop a query collection
add_query_to_collection add_query_to_collection_args 1 Add a query to a given collection
drop_query_from_collection drop_query_from_collection_args 1 Drop a query from a given collection
add_collection_to_allowlist add_collection_to_allowlist_args 1 Add a collection to the allow-list
drop_collection_from_allowlist drop_collection_from_allowlist_args 1 Drop a collection from the allow-list
set_custom_types set_custom_types_args 1 Set custom GraphQL types
create_action create_action_args 1 Create an action
drop_action drop_action_args 1 Drop an action
update_action update_action_args 1 Update an action
create_action_permission create_action_permission_args 1 Create an action permission
drop_action_permission drop_action_permission_args 1 Drop an action 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

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

Disabling schema / 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

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