API

Use HASH from your own programs over HTTP


The HASH API lets your programs read and write data in the webs you have access to. It is served at https://api.hash.ai.

This page describes what applies to every operation. Start with the Entities API to create, retrieve, and query entities.

AuthenticationCopy link to this section

Every request carries an API token in the Authorization header, with the Bearer scheme:

http
Authorization: Bearer hsh_pat_…

A request without a token, or with a token that is invalid, expired or revoked, receives 401 Unauthorized.

Creating a tokenCopy link to this section

Create a token in HASH under Settings → API tokens (app.hash.ai/settings/api-tokens). Give it a name and a lifetime between 1 and 366 days, or no expiration.

HASH shows the token only once, right after you create it, so copy it then. Keep it as secret as a password: anyone who has it can act as you.

A token is an opaque string that starts with hsh_. Its format may change, so don't parse it.

What a token can doCopy link to this section

A token acts as the user who created it. It can do what that user can do, in every web the user has access to. Its permissions follow the user's: when the user leaves a web, the token stops working there, and when the user joins a web, it starts working there. Entities created with a token are attributed to the user.

Only you can see your tokens. The settings page lists each of them with its name, the start of the token, its status, and when it was created, expires and was last used.

Replacing and revoking a tokenCopy link to this section

A token keeps the lifetime it was created with. To replace a token, create a new one, switch your programs to it, then revoke the old one in the settings.

A revoked or expired token is rejected from the next request on. When a user account is deleted, its tokens are revoked.

ErrorsCopy link to this section

Errors are Problem Details with the media type application/problem+json:

JSON
{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "API token is invalid, expired or revoked"
}
  • status is the HTTP status code of the response.
  • type identifies the kind of problem. A problem of type about:blank has no meaning beyond its HTTP status code.
  • title names the kind of problem, and detail explains this occurrence. Both are for people: don't parse them.

HASH doesn't treat replacing about:blank with a specific problem type as a breaking change. Handle a problem type you don't recognize by its HTTP status code.

The reference lists the status codes and problem types of each operation. These status codes apply to every operation:

StatusMeaning
400The request is malformed, for example its body isn't valid JSON.
401The request carries no API token, or the token is invalid, expired or revoked. The response has a WWW-Authenticate header naming the Bearer scheme.
429The request exceeded a rate limit. See Rate limits.
500An error in HASH prevented the request from completing.
503The API or its authentication is temporarily unavailable. Retry later.

Rate limitsCopy link to this section

HASH limits how many requests a client can send, so that the API stays responsive for everyone and abuse is slowed down.

Each request counts against budgets:

  • the budget of the address it comes from, which is checked before the token is;
  • the budget of the user its token belongs to, shared by all of the user's tokens and addresses.

A budget allows a burst of requests at once and refills at a steady rate. The limits may change at any time and aren't part of the API's contract, so read them from the response headers.

Rate-limit headersCopy link to this section

Each response names the budgets the request was checked against, in the RateLimit-Policy and RateLimit headers that draft-ietf-httpapi-ratelimit-headers-11 defines:

http
RateLimit-Policy: "gate";q=50;w=5
RateLimit: "gate";r=49
  • In RateLimit-Policy, q is the number of requests the budget allows at once, and w the seconds an exhausted budget takes to refill.
  • In RateLimit, r is the number of requests the budget has left after this one.

gate is the budget of the address and actor the budget of the user, so a request with a valid token names both.

Exceeding a limitCopy link to this section

A request over a budget receives 429 Too Many Requests, with a Retry-After header giving the seconds to wait. The budget it crossed reports r=0.

  • After a 429, wait at least Retry-After seconds before you retry.
  • After a 503, retry with increasing delays and some random jitter, up to a fixed number of attempts.
  • After another 4xx, change the request before you send it again.
  • Send fewer, larger requests. One POST /entities/v1 creates many entities, and POST /entities/v1/query returns pages of up to the server's maximum size.

Versioning and compatibilityCopy link to this section

The major version is part of each path, as in /entities/v1. Within a version, the API changes only in ways that don't break a client that follows this page:

  • new operations;
  • new optional request fields and query parameters;
  • new fields in responses, and new headers;
  • new values of enumerations;
  • a specific problem type in place of about:blank (see Errors);
  • changed rate limits.

So ignore response fields and headers you don't know, and handle enumeration values you don't recognize.

A change that can break a client comes with a new major version under a new path, such as /entities/v2. Breaking changes include removing or renaming an operation or a field, changing a field's type or meaning, and requiring a request field that was optional. When a new major version is released, HASH announces how long the previous one stays available.