Home

Making Your First API Request

The Karbon API uses two required headers on every request. Once you have them, you’re ready to go.

Prerequisites

  • A Karbon account with API access

Required Headers

Every request must include both of the following headers:

HeaderFormatWhere to find it
AuthorizationBearer {token}Karbon UI → Settings → Connected Apps → API Applications → your application
AccessKeyJWT (starts with eyJ...)Karbon UI → Settings → Connected Apps → API Applications → your application

Both values are issued together from the same API Application in Karbon. The Authorization token is a 36 character long GUID. The AccessKey is a JWT with three Base64URL-encoded segments separated by dots. These two values are not interchangeable — swapping them results in a 401.

This guide contains example values for Authorization and AccessKey, you’ll need to substitute in your own values in order to make a successful API request.

Base URL

https://api.karbonhq.com

All endpoints are versioned under /v3/.

Making a Request

The following examples all call GET /v3/TenantSettings — a good smoke test that returns your account configuration with no side effects.

Postman / Bruno

Postman and Bruno are desktop API clients that let you make HTTP requests without writing any code — useful for exploring the API and testing requests interactively. Bruno is open-source and stores collections as local files; Postman is cloud-based with a generous free tier.

  1. Create a new GET request to https://api.karbonhq.com/v3/TenantSettings
  2. Open the Headers tab and add:
  • Key: Authorization — Value: Bearer 550e8400-e29b-41d4-a716-446655440000
  • Key: AccessKey — Value: <your-access-key>
  1. Send the request

Tip: Store your credentials in an environment and reference them as variables (e.g. {{authToken}} and {{accessKey}}) so you don’t need to repeat them on every request.

curl

curl https://api.karbonhq.com/v3/TenantSettings \
  -H "Authorization: Bearer 550e8400-e29b-41d4-a716-446655440000" \
  -H "AccessKey: <your-access-key>"

JavaScript (fetch)

const TOKEN = process.env.KARBON_TOKEN;
const ACCESS_KEY = process.env.KARBON_ACCESS_KEY;

const response = await fetch("https://api.karbonhq.com/v3/TenantSettings", {
  headers: {
    "Authorization": `Bearer ${TOKEN}`,
    "AccessKey": ACCESS_KEY,
  },
});

if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}

const data = await response.json();
console.log(data);

JavaScript (axios)

import axios from "axios";

const client = axios.create({
  baseURL: "https://api.karbonhq.com/v3",
  headers: {
    "Authorization": `Bearer ${process.env.KARBON_TOKEN}`,
    "AccessKey": process.env.KARBON_ACCESS_KEY,
  },
});

const {data} = await client.get("/TenantSettings");
console.log(data);

Python (requests)

import os
import requests

headers = {
    "Authorization": f"Bearer {os.environ['KARBON_TOKEN']}",
    "AccessKey": os.environ["KARBON_ACCESS_KEY"],
}

response = requests.get(
    "https://api.karbonhq.com/v3/TenantSettings",
    headers=headers,
)
response.raise_for_status()
print(response.json())

Tip: Create a reusable session so headers are sent on every request automatically:

session = requests.Session()
session.headers.update(headers)

tenant = session.get("https://api.karbonhq.com/v3/TenantSettings").json()
contacts = session.get("https://api.karbonhq.com/v3/Contacts").json()

C# (.NET)

using System.Net.Http;
using System.Net.Http.Headers;

var token = Environment.GetEnvironmentVariable("KARBON_TOKEN");
var accessKey = Environment.GetEnvironmentVariable("KARBON_ACCESS_KEY");

using var client = new HttpClient { BaseAddress = new Uri("https://api.karbonhq.com/v3/") };
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
client.DefaultRequestHeaders.Add("AccessKey", accessKey);

var response = await client.GetAsync("TenantSettings");
response.EnsureSuccessStatusCode();

var json = await response.Content.ReadAsStringAsync();
Console.WriteLine(json);

Tip: Register HttpClient as a singleton (e.g., via IHttpClientFactory in ASP.NET Core) so headers are configured once and reused across requests.

Ruby (net/http)

require 'net/http'
require 'uri'
require 'json'

uri = URI('https://api.karbonhq.com/v3/TenantSettings')

response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
  request = Net::HTTP::Get.new(uri)
  request['Authorization'] = "Bearer #{ENV['KARBON_TOKEN']}"
  request['AccessKey'] = ENV['KARBON_ACCESS_KEY']
  http.request(request)
end

puts JSON.parse(response.body)

Or with the faraday gem for a cleaner interface:

require 'faraday'
require 'json'

conn = Faraday.new(url: 'https://api.karbonhq.com/v3') do |f|
  f.headers['Authorization'] = "Bearer #{ENV['KARBON_TOKEN']}"
  f.headers['AccessKey'] = ENV['KARBON_ACCESS_KEY']
  f.response :raise_error
end

response = conn.get('/TenantSettings')
puts JSON.parse(response.body)

Verifying Your Setup

A successful GET /v3/TenantSettings returns your tenant’s configuration:

{
  "ContactTypes": [
    "Individual",
    "Business"
  ],
  "WorkTypes": [
    ...
  ],
  "WorkStatuses": [
    ...
  ],
  "ClientAccessActivated": false
}

Cache this response — you’ll need WorkTypes, ContactTypes, and WorkStatuses throughout your integration.

Account-Level Access

The Karbon API operates at the account level, not the user level. When you authenticate, you are acting on behalf of the entire Karbon account — not as any individual user within it.

This means:

  • Actions taken via the API (creating work, updating contacts, recording payments) are not attributed to a specific Karbon user
  • The AccessKey is tied to your API application and the account it’s connected to, not to any individual’s login
  • All data visible within that account is accessible regardless of which user would normally see it in the Karbon UI

If your integration needs to attribute actions to a specific person (e.g., setting an assignee on a work item), you pass that user’s email address explicitly in the request body — it is not inferred from the credentials.

Common Authentication Errors

StatusMeaning
401 UnauthorizedMissing or invalid Authorization header or AccessKey

Rotating Your Access Key

Rotate your Access Key if you suspect it has been compromised, or as part of routine credential hygiene.

  1. Go to Settings → Connected Apps → API Applications
  2. Click Manage next to your application
  3. Click Rotate next to the Access Key field
  4. A confirmation dialog will appear — click Rotate to confirm

Warning: Rotating your Access Key immediately invalidates the previous key. Any existing API requests using the old key will stop working until you update them with the new value. Make sure you are ready to update all integrations before confirming.

Security Note

Never hard-code credentials in source code. Use environment variables or a secrets manager.