Overview

Zelt's Public API lets you connect your workspace to other tools and programmatically work with your data. To use the API, you create an app in Zelt, assign it the correct permissions, and generate an access token. Every API request must include this token in the Authorization header.

Credential types

CredentialDescriptionUsage
Client IDPublic identifier for your appOAuth flow only, not in API calls
Client secretPrivate key for your appOAuth flow only, never in API calls
Authorization codeShort-lived one-time code (expires in 3 minutes)Exchanged once for an access token
Access tokenThe token you use to authenticate API callsAuthorization: Bearer header on every request
Refresh tokenLong-lived token to get new access tokensToken refresh endpoint only

You cannot make API calls until you have completed step 3 and obtained an access token. Client ID and Client secret are not substitutes for an access token.


Prerequisites

  • A Zelt account with admin access
  • Permission to create and manage apps
  • Basic familiarity with HTTP requests and JSON

What you’ll do next

Complete these steps in order; each step depends on the previous one:

  1. Create an app and get your Client ID and Client secret
  2. Choose the permissions (scopes) your app needs
  3. Generate an authorization code and exchange it for an access token and refresh token
  4. Use the access token to authenticate your API calls
  5. Use the refresh token to get new access tokens without repeating the full flow

You must complete steps 1-3 before making any API calls.

After that, you can move on to the individual endpoint pages to read and update data from your Zelt account.


Quick test: verify your token works

Once you have your access token, run this before building anything else:

curl -X GET "https://go.zelt.app/apiv2/partner/users" \
  -H "Authorization: Bearer <your_access_token>"
  • 200 OK with a JSON array — your token is valid and has the user:read:all scope.
  • 401 Unauthorized — token missing, malformed, or expired (see Common Errors).
  • 403 Forbidden — token is valid but your app is missing the user:read:all scope.

Add ?includeTerminated=true to also return terminated users.


Try it in Postman or Bruno

Ready-made collections for the three calls you need to get started:

  1. Exchange authorization code for tokensPOST /oauth/authorize/token, grant_type=authorization_code
  2. Refresh the token pairPOST /oauth/authorize/token, grant_type=refresh_token
  3. List usersGET /partner/users (a token test)

Downloads

  • Postman collection (.json, Collection v2.1) — ImportFile. Requests 1 and 2 save the returned accessToken / refreshToken back into the collection variables automatically.
  • Bruno collection (.yaml) — Import Collection. Copy the tokens from response 1 or 2 into your accessToken / refreshToken variables before running request 3.

Variables to fill in

VariableWhere it comes from
baseUrlhttps://go.zelt.app/apiv2 (pre-filled)
clientId / clientSecretYour app in Zelt — see Create an app
authorizationCodeThe code on your redirect URI after you authorise the app. Single use, expires in 3 minutes — grab a fresh one right before running request 1.
redirectUriOnly if your app was configured with one; it must match exactly. (Postman: enable the disabled redirect_uri field. Bruno: add it to the form body.)
accessToken / refreshTokenThe token pair returned by request 1 or 2. Use the newest pair before running request 3.

The Authorization: Basic header on requests 1 and 2 is base64(clientId:clientSecret) — both
tools build it from the Basic-auth fields, you don't encode anything yourself.

The raw requests, for reference

1 — Authorization code → token pair

curl -X POST "https://go.zelt.app/apiv2/oauth/authorize/token" \
  -u "CLIENT_ID:CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTHORIZATION_CODE"
  # -d "redirect_uri=YOUR_REDIRECT_URI"   # only if your app has one configured

2 — Refresh token → new token pair

curl -X POST "https://go.zelt.app/apiv2/oauth/authorize/token" \
  -u "CLIENT_ID:CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=REFRESH_TOKEN"

Both return:

{ "access_token": "eyJhbGciOi...", "refresh_token": "eyJhbGciOi..." }

The access token is valid for 1 hour; the refresh token for 90 days. Each refresh
rotates the refresh token — always store the newest pair.

3 — Authenticated call

curl -X GET "https://go.zelt.app/apiv2/partner/users" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Common errors

HTTP statusLikely causeFix
401 UnauthorizedToken missing, expired, or malformedCheck the Authorization: Bearer <token> header format; re-generate token if expired
403 ForbiddenToken is valid but lacks the required scopeAdd the needed scope to your app and regenerate the token
200 OK with empty resultsToken is valid, but no scopes are assignedGo to the Permissions page and assign scopes before generating the token
400 Bad RequestMalformed request bodyCheck JSON formatting and required fields for that endpoint