Hex API
Programmatically run Hex projects with the API.
Available on the Team and Enterprise plans.
The Hex public API provides a way to trigger runs of published Hex projects. If you are looking to trigger these runs from an orchestrator, check out the Hex-managed Airflow and Dagster integrations, or the vendor-managed Shipyard integration. For path parameters and schema of specific endpoints, view the API reference.
Authentication
API Requests are authenticated using Oauth 2.0 Bearer Tokens in the header of the HTTP request. The token is always bound to a single Hex user's account and requests are executed as that Hex user, meaning the user can only execute requests against projects that are in line with the current permissions for that project.
Token creation
There are two types of tokens users can create: Personal access tokens and Workspace tokens.
Personal access tokens
Personal access tokens mirror the same permissions that a user has within the Hex product. They can be created by anyone with an Editor or higher workspace role. Unlike workspace tokens (which can have no expiration), they must be configured to expire after a fixed duration.
Enforcing token expiration for personal access tokens ensures that tokens are rotated frequently.
To create a Personal access token, head to the API keys page, under the Account section. Then, select the New Token button and provide a description and an expiration time frame. An existing token can be regenerated at any time by selecting the three-dot menu to the right of the token, and selecting Regenerate.
Regenerating a personal access token will generate a new value for the token and immediately revoke the existing token.
If a user is deactivated in a workspace, their personal access tokens will no longer work.
Workspace tokens
Workspace tokens are created, managed, and shared by Admins of a workspace. Unlike personal access token, workspace tokens can be configured to never expire. This more permissive setting is available for workspace tokens, since any Admin can revoke this token at any time.
To create a Workspace token, head to the API keys page, under the Account section. Then, select the New Token button and provide a description and an expiration time frame. Workspace tokens can be configured to have the following scopes:
- Read only: The token will work with any API endpoint that only gets information (e.g.
ListProjects
andGetProjectRuns
). - Run projects: The token will also work with the RunProjects endpoint.
If you are creating a token that is used to orchestrate projects across a workspace, consider using a Workspace token so that the token is not scoped to an individual user.
Comparison
Feature | Personal access token | Workspace token |
---|---|---|
Required workspace role | Editor or higher | Admin only |
Maximum expiration | Follows expiration rules configured by Admins | Can be configured to never expire |
Permissions | Mirrors an individual user's permissions | Mirrors the admin permissions for the workspace, with additional configuration for scopes |
Token expiration
When creating a token, users can specify an expiration period:
- Personal access tokens: When creating a personal access token, users can specify a time to live that is equal to, or less than, the maximum expiration time configured by an Admin (see below). Durations may include 7, 30, 60, 90, or 120 days.
- Workspace tokens: When creating a workspace token, admins can specify an expiration that is a fixed duration (one of 7, 30, 60, 90, or 120 days), or no expiry.
To configure the maximum expiration for a personal access token, Admins can head to the Integrations page, under the Workspace section of Settings.
Users will receive an email notification 72 hours before and 24 hours before any token expires, warning them that the token will be expiring soon. Tokens can be manually revoked by clicking the three-dot menu to the right of the token, and selecting Revoke. Once a token is revoked or expired, the token can never again be used to authenticate requests.
Using the API
The Hex API allows users to programmatically run published Hex projects. This makes it simple to run projects with specific inputs, and allows for automation of workflows that update cached query results and the cached state of an app. The full reference docs for the API can be found here.
The below examples use the requests package to run the API, though the API can be invoked by many other methods (e.g. running a cURL command).
Setup needed for the API
To use the API correctly, first run some setup code. Ensure that you replace values for your specific use-case.
- Base URL: For most Hex users, this will be
https://app.hex.tech/api/v1
. Single-tenant app users should replace theapp.hex.tech
part of this URL with the URL they use to access Hex (e.g.atreides.hex.tech
). - Project ID: The project ID can be found by visiting the project you wish to run, and copying it from the URL — the ID is the part of the URL after the
/hex/
. Additionally, the project ID can be found in the Variables view of the sidebar. - Token: See the above section on token creation. Consider using a secret to store this more securely.
import requests
# Single tenant users will need to replace this with their Hex URL
BASE_URL = 'https://app.hex.tech/api/v1'
# Replace this with the project ID
PROJECT_ID = '5a8591dd-4039-49df-9202-96385ba3eff8'
# Replace this with your token
TOKEN = '5bbf1c8b1989d6657d5c'
Run a published project with default inputs
This API call uses the RunProject
endpoint to run a published project with its default inputs. It does not update the cache for this project.
response = requests.post(
url=f"{BASE_URL}/project/{PROJECT_ID}/run",
headers={"Authorization" : f"Bearer {TOKEN}"}
)
The response from this request will contain a runUrl
which will display the results of the project run as a Snapshot, viewable by any user who has at least view access to the project.
Run a published project with custom inputs
The RunProject
endpoint contains an optional inputParams
body parameter that allows users to specify the values for Input parameters to be used in the project run.
inputs = {
"inputParams": {
"user_name": "j_doe",
"team": "finance",
"id": 1234567890
}
}
response = requests.post(
url=f"{BASE_URL}/project/{PROJECT_ID}/run",
json=inputs,
headers={"Authorization" : f"Bearer {TOKEN}"}
)
Update the cached state and query cache of a published project
The RunProject API allows control over two key caching options: updatePublishedResults
for updating the published app's state, and useCachedSqlResults
for controlling whether cached SQL results are used.
updatePublishedResults: When updatePublishedResults
is set to false in a RunProject
request (the default), the project run will not update the published app state. When updatePublishedResults
is set to true, the project run will update the cached state of the published app with the latest run results. This ensures that viewers see the results generated by the run when they open the app.
In order to set updatePublishedResults
to true, "Show results from a publish, or scheduled run" must be enabled. If inputParams
are included in the request with updatePublishedResults
set to true, the provided parameter values will be ignored, as updating the published app’s cache state requires the default Input parameter values to be used.
useCachedSqlResults: When useCachedSqlResults
is set to true in a RunProject
request (the default), the project will use cached SQL results if available. When useCachedSqlResults
is set to false, SQL cells will run without hitting the cache, essentially refreshing the cached SQL query results for future runs.
In order for a query to execute and update cached results using useCachedSqlResults
, "Use SQL caching in published app" must be enabled on the project’s Published app run settings.
# Forces a fresh run of SQL queries and updates the published app with new results
inputs = {
"useCachedSqlResults": "false",
"updatePublishedResults": "true"
}
response = requests.post(
url=f"{BASE_URL}/project/{PROJECT_ID}/run",
json=inputs,
headers={"Authorization" : f"Bearer {TOKEN}"}
)
Cancel active runs for a project
Project runs can be cancelled using the CancelRun
endpoint. This can be especially useful if project runs triggered by the API are contributing to database performance degradation, or your user is running into the kernel limit. The GetProjectRuns
endpoint can be used in conjunction with this in order to easily cancel all project runs.
# Get all runs for project
response = requests.get(
url=f"{BASE_URL}/project/{PROJECT_ID}/runs",
params={"limit": 25, "statusFilter": "RUNNING"},
headers={"Authorization" : f"Bearer {TOKEN}"}
)
response = response.json()
# Iterate through runs and cancel them
for run in response["runs"]:
run_id = run["runId"]
requests.delete(
url=f"{BASE_URL}/project/{PROJECT_ID}/run/{run_id}",
headers={"Authorization" : f"Bearer {TOKEN}"}
)
Kernel and rate limits
Users are limited to 60 API requests per minute. If a user exceeds 60 requests in a minute, subsequent requests will be denied and return a 429 status until the rate limit is reset, 60 seconds after the first request. Request response headers contain metadata about the remaining number of requests allowed, and when the rate limit will be reset.
Users are also limited to 25 concurrently running kernels between projects opened in the Hex UI and project runs triggered via the API. Each RunProject
request will use a single kernel until the project run completes. Once 25 kernels are running, subsequent RunProject
requests will result in a 503 status code, with no project run created. In addition to this, projects opened in the UI that do not already have a running kernel will show an error that you have reached the maximum number of running kernels. Cancelling a project run using the CancelRun
endpoint will stop a running kernel and free it for use via the UI or API.
The API and hextoolkit
The hextoolkit contains a wrapper for all of the Hex API's functionality. This section is a brief overview of the functionality and syntax. You can view all of the ApiClient methods, their arguments, and their return objects in the API reference docs.
Create the client
To make requests using the hextoolkit
, you will need to generate an ApiClient with your token. We recommend storing this token as a secret.
import hextoolkit as htk
import hex_api
api_client = htk.get_api_client(TOKEN)
Get project metadata
Metadata can be fetched for an individual project via the get_project
endpoint or for up to 100 projects via the list_projects
endpoint.
single_project = api_client.get_project(project_id=PROJECT_ID)
many_projects = api_client.list_projects(limit=100)
A ProjectApiResource
is returned from the get_project
endpoint, which contains various pieces of metadata about the project (see the API Reference docs for the complete object structure). The list_projects
endpoint will return a list of these, as well as a pagination
object containing cursor information for fetching the next page of projects. You can pass in the pagination.after
cursor string into a subsequent list_projects()
request in order to continue fetching new projects. When the end of pagination has been reached, the after
value will be None
. See below for an example of a loop to fetch metadata for all projects in a workspace:
first_page = client.list_projects(limit=100)
after = first_page.pagination.after
projects = first_page.values
while after:
response = client.list_projects(limit = 100, after=after)
after = response.pagination.after
new_projects = response.values
projects = [*projects, *new_projects]
Run projects
Running a project with no inputs is as simple as specifying the project_id
:
project_run = api_client.run_project(project_id=PROJECT_ID)
The run_project
method returns a ProjectRunResponsePayload
object containing metadata, as well as a run_url
where you can view the results.
It is also possible to run a project with inputs or to update the cache of a project using the run_project_request_body argument
:
# Run a project with inputs
input_request_body = hex_api.RunProjectRequestBody(
input_params={
"input_parameter_name": "input_parameter_value",
...
}
)
# Set a new cache
update_cache_request_body = hex_api.RunProjectRequestBody(
update_cache=True
)
# Update the value used for run_project_request_body depending on desired behavior
project_run = api_client.run_project(project_id=PROJECT_ID, run_project_request_body=input_request_body)
Get a run status
The status of a run can be viewed using the run_status_url
as part of the returned object from the run_project
method. The get_run_status
method can also be used to programmatically check the status of a run:
project_run = api_client.run_project(project_id=PROJECT_ID)
status = api_client.get_run_status(project_id=PROJECT_ID, run_id=project_run.run_id)
Cancel a project run
Project runs can be cancelled using the cancel_run
method:
project_run = api_client.run_project(project_id=PROJECT_ID)
api_client.cancel_run(project_id=PROJECT_ID, run_id=project_run.run_id)
Get all project runs
All runs of a given project can be retrieved using the get_project_runs
method. The project runs can be filtered using the status_filter
argument to easily identify project runs that have completed, errored, etc.
active_runs = api_client.get_project_runs(project_id=PROJECT_ID, status_filter='RUNNING')
Troubleshooting
401 Unauthorized
A 401 status code indicates that Hex was unable to authenticate the request. Make sure that a token is being included in the header of your request, and that you have specified a valid base URL. If you are including a token in the header of the request, double-check that the token has not expired and consider regenerating the token or creating a new token.
404 Not found
A 404 status code indicates that Hex was unable to find the resource referenced. This could mean that the project ID or run ID included in the request are not accurate, or that your user does not have permission for the requested resource. Double-check that the user an access the Hex project in the UI.
422 Unprocessable Entity
A 422 status code can indicate that you are attempting to interact with a project that hasn't been published, or that you have provided invalid input parameters as a part of your request. Double-check that your app has been published, and that any input parameters provided are correctly specified.
429 Too many requests
A 429 status code indicates that you have hit the request rate limit. See the section on rate limiting above for more information.
500 Internal server error
A 500 status code indicates an error with the Hex application. Please contact Hex support for help troubleshooting.
503 Service Unavailable
A 503 status code indicates that the user has reached the maximum number of concurrently running kernels. See the section on kernel limits above for more information.