# Generate a complete bodygraph
Source: https://docs.humandesignapi.nl/api-reference/bodygraph/generate-a-complete-bodygraph
/openapi/v1-routes.yaml post /bodygraphs
Generates a full Human Design bodygraph chart from birth data and location.
# Generate a simplified bodygraph
Source: https://docs.humandesignapi.nl/api-reference/bodygraph/generate-a-simplified-bodygraph
/openapi/v1-routes.yaml post /bodygraphs/simple
Generates a simplified Human Design chart with type, profile, gates, channels, and centers.
# Generate a chart from coordinates
Source: https://docs.humandesignapi.nl/api-reference/charts/generate-a-chart-from-coordinates
/openapi/v2-routes.yaml post /charts/coordinates
Generates a complete Human Design chart from birth date, time, and geographic coordinates.
No geocoding key required — timezone is resolved from lat/lng directly.
Requires the "advanced" access tier.
# Generate a full chart
Source: https://docs.humandesignapi.nl/api-reference/charts/generate-a-full-chart
/openapi/v2-routes.yaml post /charts
Generates a complete Human Design chart from birth date, time, and location.
Requires the "advanced" access tier.
# Generate a simple chart
Source: https://docs.humandesignapi.nl/api-reference/charts/generate-a-simple-chart
/openapi/v2-routes.yaml post /charts/simple
Generates a simplified Human Design chart with type, profile, gates, channels, and centers.
Available to any access tier.
# Error Codes
Source: https://docs.humandesignapi.nl/api-reference/error-codes
Complete reference of all machine-readable error codes.
Always use the `errorCode` field for programmatic error handling. The `message` field is human-readable and may change without notice.
```json theme={null}
{
"success": false,
"errorCode": "INVALID_BIRTHDATE",
"message": "Birthdate must be in YYYY-MM-DD format"
}
```
## Authentication Errors
| Error Code | HTTP Status | Description | Action |
| --------------------- | ----------- | ------------------------------------------------------- | ------------------------------------------------------------------------------- |
| `API_KEY_MISSING` | 401 | No `Authorization` header provided | Add `Authorization: Bearer YOUR_KEY` header |
| `API_KEY_INVALID` | 401 | API key not found or deactivated | Check your key in the dashboard |
| `GEOCODE_KEY_MISSING` | 401 | No `HD-Geocode-Key` header on a location-based endpoint | Add the header, or use the [coordinates endpoint](/guides/coordinates-endpoint) |
| `UNAUTHORIZED` | 401 | General authentication failure | Verify your credentials |
## Authorization Errors
| Error Code | HTTP Status | Description | Action |
| ------------------ | ----------- | ---------------------------------------- | ------------------------------------------------------------------------------- |
| `ACCESS_DENIED` | 403 | Your plan does not include this endpoint | Upgrade to a plan with the required [access tier](/authentication#access-tiers) |
| `ACCOUNT_INACTIVE` | 403 | Account has been deactivated | Contact [support](mailto:info@mail.humandesignapi.nl) |
## Billing Errors
| Error Code | HTTP Status | Description | Action |
| ------------------- | ----------- | -------------------------------------------- | ------------------------------------------------------------ |
| `CREDITS_EXHAUSTED` | 402 | No credits remaining and overage is disabled | Wait for monthly reset, enable overage, or upgrade your plan |
## Validation Errors
| Error Code | HTTP Status | Description | Action |
| ------------------------ | ----------- | ---------------------------------------------------------- | -------------------------------------------------------- |
| `INVALID_BIRTHDATE` | 400 | Birthdate is missing or not in `YYYY-MM-DD` format | Use ISO 8601 format: `"1990-01-15"` |
| `INVALID_BIRTHTIME` | 400 | Birthtime is missing or not in `HH:MM` format | Use 24-hour format: `"14:30"` |
| `INVALID_LOCATION` | 400 | Location is empty or shorter than 4 characters | Provide a valid location: `"Amsterdam, The Netherlands"` |
| `INVALID_LATITUDE` | 400 | Latitude is missing, not a number, or outside -90 to 90 | Provide a valid latitude: `52.3676` |
| `INVALID_LONGITUDE` | 400 | Longitude is missing, not a number, or outside -180 to 180 | Provide a valid longitude: `4.9041` |
| `MISSING_REQUIRED_FIELD` | 400 | A required field is missing from the request body | Check the endpoint documentation for required fields |
| `INVALID_REQUEST_BODY` | 422 | Request body is malformed or has structural errors | Ensure valid JSON with correct field types |
## Service Errors
| Error Code | HTTP Status | Description | Action |
| ---------------------------- | ----------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `GEOCODE_FAILED` | 400 | Google Geocoding service returned an error | Check your geocoding key and try again |
| `GEOCODE_KEY_INVALID` | 400 | Google Geocoding API key is invalid or restricted | Verify your key in Google Cloud Console |
| `GEOCODE_LOCATION_NOT_FOUND` | 400 | Location could not be geocoded | Check spelling, try a more specific location, or use [coordinates](/guides/coordinates-endpoint) |
| `GEOCODE_RATE_LIMITED` | 429 | Google Geocoding rate limit exceeded | Wait and retry, or use the [coordinates endpoint](/guides/coordinates-endpoint) |
| `TIMEZONE_LOOKUP_FAILED` | 500 | Could not determine timezone for the location | Try a nearby major city, or use coordinates with a known timezone |
| `EPHEMERIS_ERROR` | 500 | Astronomical calculation failed | Contact [support](mailto:info@mail.humandesignapi.nl) if this persists |
| `CHART_GENERATION_FAILED` | 500 | Chart generation failed unexpectedly | Contact [support](mailto:info@mail.humandesignapi.nl) if this persists |
| `INTERNAL_ERROR` | 500 | Unexpected server error | Contact [support](mailto:info@mail.humandesignapi.nl) if this persists |
## Rate Limiting
| Error Code | HTTP Status | Description | Action |
| --------------------- | ----------- | ----------------- | -------------------------------------------------------------------- |
| `RATE_LIMIT_EXCEEDED` | 429 | Too many requests | Wait for the `Retry-After` header value (in seconds) before retrying |
See [Rate Limiting](/guides/rate-limiting) for limit details.
# v1 API Overview (Legacy)
Source: https://docs.humandesignapi.nl/api-reference/v1/overview
Overview of the legacy v1 Bodygraph API.
v1 is supported but no longer recommended for new integrations. Use the [v2 API](/api-reference/v2/overview) instead. See the [migration guide](/migration/v1-to-v2) for upgrade instructions.
## Base URL
```
https://api.humandesignapi.nl/v1
```
## Authentication
v1 uses two custom headers (not Bearer token):
```
HD-Api-Key: YOUR_API_KEY
HD-Geocode-Key: YOUR_GEOCODE_KEY
```
Both are required for all v1 endpoints.
## Endpoints
| Endpoint | Description | Access Tier |
| ---------------------------- | -------------------------------------------------------------- | ---------------- |
| `POST /v1/bodygraphs` | Full bodygraph with all properties | Advanced |
| `POST /v1/bodygraphs/simple` | Simplified bodygraph (type, profile, gates, channels, centers) | Basic + Advanced |
## Request Format
| Field | Type | Format | Example |
| ----------- | ------ | --------------------------- | ------------------------------ |
| `birthdate` | string | `DD-MMM-YY` | `"15-Jan-90"` |
| `birthtime` | string | `HH:MM` (24h) | `"14:30"` |
| `location` | string | City, Country (min 4 chars) | `"Amsterdam, The Netherlands"` |
v1 uses `DD-MMM-YY` date format (e.g., `"15-Jan-90"`). v2 uses ISO 8601 `YYYY-MM-DD` format.
## Response Format
v1 returns chart data as a flat JSON object without a response envelope. Field names use `snake_case`:
```json theme={null}
{
"type": "Generator",
"profile": "6/2",
"channels_short": ["20-34", "10-57"],
"centers": ["G", "Sacral", "Spleen", "Throat"],
"strategy": "To Respond",
"authority": "Sacral",
"incarnation_cross": "Right Angle Cross of Tension (39/38 | 51/57)"
}
```
## Key Differences from v2
| Aspect | v1 | v2 |
| -------------------- | ---------------- | ----------------------------------- |
| Auth header | `HD-Api-Key` | `Authorization: Bearer` |
| Date format | `DD-MMM-YY` | `YYYY-MM-DD` |
| Response | Flat JSON object | Standard envelope with `data` field |
| Field naming | `snake_case` | `camelCase` |
| Error codes | Limited | Comprehensive, machine-readable |
| Coordinates endpoint | Not available | Available |
# v2 API Overview
Source: https://docs.humandesignapi.nl/api-reference/v2/overview
Overview of the v2 Human Design Chart API.
The v2 API is the recommended version for all new integrations. It returns structured JSON with a consistent [response envelope](/response-format), camelCase field names, and machine-readable [error codes](/api-reference/error-codes).
## Base URL
```
https://api.humandesignapi.nl/v2
```
## Authentication
All endpoints require an API key as a Bearer token:
```
Authorization: Bearer YOUR_API_KEY
```
Location-based endpoints additionally require a geocoding key:
```
HD-Geocode-Key: YOUR_GEOCODE_KEY
```
See [Authentication](/authentication) for details.
## Endpoints
| Endpoint | Description | Access Tier | Geocode Key |
| ----------------------------- | ---------------------------------------------------------- | ---------------- | ----------- |
| `POST /v2/charts` | Full chart with all properties | Advanced | Required |
| `POST /v2/charts/simple` | Simplified chart (type, profile, gates, channels, centers) | Basic + Advanced | Required |
| `POST /v2/charts/coordinates` | Full chart from latitude/longitude | Advanced | Not needed |
## Request Format
All endpoints accept `application/json` with:
| Field | Type | Format | Example |
| ----------- | ------ | --------------------------- | ------------------------------ |
| `birthdate` | string | `YYYY-MM-DD` | `"1990-01-15"` |
| `birthtime` | string | `HH:MM` (24h) | `"14:30"` |
| `location` | string | City, Country (4-200 chars) | `"Amsterdam, The Netherlands"` |
The coordinates endpoint replaces `location` with `lat` (number, -90 to 90) and `lng` (number, -180 to 180).
## Content Type
```
Content-Type: application/json
```
## Credits
Each successful API call costs 1 credit. See [Plans & Credits](/guides/plans-and-credits).
# Generate a chart with a rendered image
Source: https://docs.humandesignapi.nl/api-reference/visual-charts/generate-a-chart-with-a-rendered-image
/openapi/v2-routes.yaml post /visual-charts
Generates a complete Human Design chart from birth date, time, and location,
and returns a `svgRenderUrl` for the rendered Visual Chart image alongside the
chart data. Requires the "advanced" access tier.
# Generate a chart with a rendered image from coordinates
Source: https://docs.humandesignapi.nl/api-reference/visual-charts/generate-a-chart-with-a-rendered-image-from-coordinates
/openapi/v2-routes.yaml post /visual-charts/coordinates
Generates a complete Human Design chart from birth date, time, and geographic
coordinates, and returns a `svgRenderUrl` for the rendered Visual Chart image
alongside the chart data. No geocoding key required — timezone is resolved from
lat/lng directly. Requires the "advanced" access tier.
# Authentication
Source: https://docs.humandesignapi.nl/authentication
How to authenticate with the Human Design API.
## v2 Authentication (Recommended)
All v2 endpoints require your API key as a Bearer token:
```
Authorization: Bearer YOUR_API_KEY
```
### Geocoding Key
Location-based endpoints (`/v2/charts` and `/v2/charts/simple`) additionally require a Google Geocoding API key:
```
HD-Geocode-Key: YOUR_GEOCODE_KEY
```
This key is used to convert location strings (e.g., "Amsterdam, The Netherlands") into geographic coordinates. You can get one from the [Google Cloud Console](https://developers.google.com/maps/documentation/geocoding/get-api-key).
The [coordinates endpoint](/guides/coordinates-endpoint) (`/v2/charts/coordinates`) does **not** need a geocoding key. If you already have latitude and longitude, use it to skip geocoding entirely.
### Full Request Example
```bash theme={null}
curl -X POST https://api.humandesignapi.nl/v2/charts/simple \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "HD-Geocode-Key: YOUR_GEOCODE_KEY" \
-d '{
"birthdate": "1990-01-15",
"birthtime": "14:30",
"location": "Amsterdam, The Netherlands"
}'
```
## v1 Authentication (Legacy)
v1 uses a different header format. New integrations should use v2. See the [migration guide](/migration/v1-to-v2).
v1 endpoints require two custom headers:
```
HD-Api-Key: YOUR_API_KEY
HD-Geocode-Key: YOUR_GEOCODE_KEY
```
The same API key works for both v1 and v2 — only the header name changes.
## Access Tiers
Your plan determines which endpoints you can access:
| Tier | Endpoints | Plans |
| ------------ | ---------------------------------------------------------------------------------- | -------------------------- |
| **Basic** | `/v2/charts/simple`, `/v1/bodygraphs/simple` | Hobbyist |
| **Advanced** | All endpoints (including `/v2/charts`, `/v2/charts/coordinates`, `/v1/bodygraphs`) | Developer, Scale, Lifetime |
Calling an endpoint above your tier returns `403` with error code `ACCESS_DENIED`.
## API Key Security
Keep your API key secret. Never expose it in client-side code, public repositories, or browser requests.
* Your API key is available in the [dashboard](https://humandesignapi.nl/dashboard)
* If your key is compromised, rotate it immediately from the dashboard. The old key is **invalidated instantly**
* Each API call deducts one credit from your plan's allocation
## Authentication Errors
| Error Code | Status | Description |
| --------------------- | ------ | ------------------------------------------------------- |
| `API_KEY_MISSING` | 401 | No `Authorization` header provided |
| `API_KEY_INVALID` | 401 | API key not found or deactivated |
| `GEOCODE_KEY_MISSING` | 401 | No `HD-Geocode-Key` header on a location-based endpoint |
| `GEOCODE_KEY_INVALID` | 400 | Google Geocoding API key is invalid or restricted |
| `ACCESS_DENIED` | 403 | Your plan does not include this endpoint |
| `ACCOUNT_INACTIVE` | 403 | Account has been deactivated |
# Using with AI Agents & LLMs
Source: https://docs.humandesignapi.nl/guides/agentic-tools
Integrate the Human Design API with AI agents, LLMs, and no-code tools.
The Human Design API is designed for programmatic consumption: structured JSON, machine-readable error codes, a consistent response envelope, and a comprehensive OpenAPI spec. This makes it straightforward to integrate as a tool for AI agents and LLM workflows.
## Why This API Works Well with AI
* **Consistent structure** — every response has the same envelope (`success`, `errorCode`, `data`)
* **Machine-readable errors** — agents can branch on `errorCode` without parsing text
* **camelCase fields** — no special casing surprises for JSON parsers
* **OpenAPI spec** — import directly into tool-building frameworks
* **Deterministic** — same birth data always produces the same chart
## llms.txt
This documentation site serves an auto-generated `llms.txt` file:
```
https://docs.humandesignapi.nl/llms.txt
```
Feed this to your LLM for full API context. A more comprehensive `llms-full.txt` with the complete documentation content is also available at `/llms-full.txt`.
## OpenAI Function Calling
Define the API as a tool in the OpenAI function calling format:
```json theme={null}
{
"type": "function",
"function": {
"name": "generate_human_design_chart",
"description": "Generate a Human Design personality chart from birth data. Returns type, profile, gates, channels, and centers.",
"parameters": {
"type": "object",
"properties": {
"birthdate": {
"type": "string",
"description": "Date of birth in YYYY-MM-DD format"
},
"birthtime": {
"type": "string",
"description": "Time of birth in HH:MM 24-hour format"
},
"location": {
"type": "string",
"description": "Birth location as city and country"
}
},
"required": ["birthdate", "birthtime", "location"],
"additionalProperties": false
},
"strict": true
}
}
```
When the LLM invokes this tool, make the API call:
```javascript JavaScript theme={null}
const response = await fetch("https://api.humandesignapi.nl/v2/charts/simple", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY",
"HD-Geocode-Key": "YOUR_GEOCODE_KEY",
},
body: JSON.stringify({ birthdate, birthtime, location }),
});
const result = await response.json();
return result.success ? result.data : { error: result.errorCode };
```
```python Python theme={null}
import requests
response = requests.post(
"https://api.humandesignapi.nl/v2/charts/simple",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY",
"HD-Geocode-Key": "YOUR_GEOCODE_KEY",
},
json={"birthdate": birthdate, "birthtime": birthtime, "location": location},
)
result = response.json()
return result["data"] if result["success"] else {"error": result["errorCode"]}
```
## Claude Tool Use
Define as an Anthropic tool:
```json theme={null}
{
"name": "generate_human_design_chart",
"description": "Generate a Human Design personality chart from birth date, time, and location. Returns type, profile, gates, channels, and defined centers.",
"input_schema": {
"type": "object",
"properties": {
"birthdate": {
"type": "string",
"description": "Date of birth in YYYY-MM-DD format (e.g., 1990-01-15)"
},
"birthtime": {
"type": "string",
"description": "Time of birth in HH:MM 24-hour format (e.g., 14:30)"
},
"location": {
"type": "string",
"description": "Birth location as city and country (e.g., Amsterdam, The Netherlands)"
}
},
"required": ["birthdate", "birthtime", "location"]
}
}
```
## Coordinates Endpoint for Agents
If your agent already has latitude and longitude (e.g., from a prior geocoding step), use the [coordinates endpoint](/guides/coordinates-endpoint) to skip the geocoding key entirely:
```javascript JavaScript theme={null}
const response = await fetch("https://api.humandesignapi.nl/v2/charts/coordinates", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY",
},
body: JSON.stringify({
birthdate: "1990-01-15",
birthtime: "14:30",
lat: 52.3676,
lng: 4.9041,
}),
});
```
```python Python theme={null}
import requests
response = requests.post(
"https://api.humandesignapi.nl/v2/charts/coordinates",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY",
},
json={
"birthdate": "1990-01-15",
"birthtime": "14:30",
"lat": 52.3676,
"lng": 4.9041,
},
)
```
This returns a full [`ChartResult`](/response-format#data-types) without requiring an `HD-Geocode-Key` header.
## No-Code Platforms (Zapier, Make, n8n)
Use an HTTP request module with these settings:
| Setting | Value |
| ----------- | ---------------------------------------------------------------------------------------------------------- |
| **Method** | POST |
| **URL** | `https://api.humandesignapi.nl/v2/charts/simple` |
| **Headers** | `Authorization: Bearer YOUR_API_KEY`, `HD-Geocode-Key: YOUR_GEOCODE_KEY`, `Content-Type: application/json` |
| **Body** | `{"birthdate": "YYYY-MM-DD", "birthtime": "HH:MM", "location": "City, Country"}` |
Map dynamic fields from your workflow into the body. Parse `data` from the response for the chart result.
## Recommended Endpoints for Agents
| Use Case | Endpoint | Why |
| ------------------------- | ----------------------------- | -------------------------------- |
| Quick personality summary | `POST /v2/charts/simple` | Smaller response, all plan tiers |
| Full chart reading | `POST /v2/charts` | All properties, advanced tier |
| Agent with geocoding | `POST /v2/charts/coordinates` | No geocode key needed |
## Error Handling for Agents
Always check `success` and branch on `errorCode`:
```javascript JavaScript theme={null}
if (!result.success) {
if (result.errorCode === "CREDITS_EXHAUSTED") {
return "Credit limit reached. Please try again later.";
} else if (result.errorCode === "INVALID_BIRTHDATE") {
return "Please provide the birth date in YYYY-MM-DD format.";
} else {
return `API error: ${result.errorCode}`;
}
}
```
```python Python theme={null}
if not result["success"]:
if result["errorCode"] == "CREDITS_EXHAUSTED":
return "Credit limit reached. Please try again later."
elif result["errorCode"] == "INVALID_BIRTHDATE":
return "Please provide the birth date in YYYY-MM-DD format."
else:
return f"API error: {result['errorCode']}"
```
See the full [Error Codes](/api-reference/error-codes) reference.
# Using Coordinates Instead of Location
Source: https://docs.humandesignapi.nl/guides/coordinates-endpoint
Generate charts from latitude and longitude without a geocoding key.
The coordinates endpoint (`POST /v2/charts/coordinates`) generates a full Human Design chart from latitude and longitude. No Google Geocoding API key required.
## Why Use Coordinates
* **No geocoding key needed** — one less API key to manage
* **Full control** — use your own geocoding service or pre-resolved coordinates
* **Ideal for agents** — if your AI agent already has lat/lng from a prior step, skip geocoding entirely
* **No geocoding rate limits** — avoid `GEOCODE_RATE_LIMITED` errors
## Request Format
```bash theme={null}
curl -X POST https://api.humandesignapi.nl/v2/charts/coordinates \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"birthdate": "1990-01-15",
"birthtime": "14:30",
"lat": 52.3676,
"lng": 4.9041
}'
```
| Field | Type | Constraints | Example |
| ----------- | ------ | ------------- | -------------- |
| `birthdate` | string | `YYYY-MM-DD` | `"1990-01-15"` |
| `birthtime` | string | `HH:MM` (24h) | `"14:30"` |
| `lat` | number | -90 to 90 | `52.3676` |
| `lng` | number | -180 to 180 | `4.9041` |
## How It Works
The API resolves the timezone directly from the coordinates using geographic timezone lookup, then calculates the chart. No external geocoding call is made.
## Response
Returns the same full [`ChartResult`](/response-format#data-types) as `POST /v2/charts`:
```json theme={null}
{
"timestamp": "2026-03-24T12:00:00.000Z",
"success": true,
"message": "Chart generated",
"errorCode": "",
"type": "ChartResult",
"data": {
"type": "Generator",
"profile": "6/2",
"channelsShort": ["20-34", "10-57"],
"centers": ["G", "Sacral", "Spleen", "Throat"],
"strategy": "To Respond",
"authority": "Sacral",
"incarnationCross": "Right Angle Cross of Tension (39/38 | 51/57)",
...
}
}
```
## Access Tier
Requires **Advanced** tier (Developer, Scale, or Lifetime plan). Basic tier plans receive `403 ACCESS_DENIED`.
## When to Use Location vs. Coordinates
| Scenario | Recommended Endpoint |
| ------------------------------------ | -------------------------------------------------------- |
| User types a city name | `/v2/charts` or `/v2/charts/simple` (uses geocoding) |
| You already have lat/lng | `/v2/charts/coordinates` |
| Building an AI agent | `/v2/charts/coordinates` (avoids geocode key dependency) |
| Want to avoid Google Geocoding costs | `/v2/charts/coordinates` |
## Validation Errors
| Error Code | Description |
| ------------------------ | ---------------------------------------------------------- |
| `INVALID_LATITUDE` | Latitude is missing, not a number, or outside -90 to 90 |
| `INVALID_LONGITUDE` | Longitude is missing, not a number, or outside -180 to 180 |
| `TIMEZONE_LOOKUP_FAILED` | Could not determine timezone for the given coordinates |
# Error Handling
Source: https://docs.humandesignapi.nl/guides/error-handling
How to handle errors from the Human Design API.
All v2 error responses use the same [response envelope](/response-format) as success responses. This makes error handling consistent and predictable.
## Basic Pattern
```json theme={null}
{
"timestamp": "2026-03-24T12:00:01.000Z",
"success": false,
"message": "Birthdate must be in YYYY-MM-DD format",
"errorCode": "INVALID_BIRTHDATE",
"type": "",
"data": null
}
```
1. **Check `success`** — if `false`, the request failed
2. **Read `errorCode`** — use this for programmatic logic
3. **Never parse `message`** — it is human-readable and may change without notice
```javascript JavaScript theme={null}
const response = await fetch("https://api.humandesignapi.nl/v2/charts/simple", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY",
"HD-Geocode-Key": "YOUR_GEOCODE_KEY",
},
body: JSON.stringify({ birthdate: "1990-01-15", birthtime: "14:30", location: "Amsterdam" }),
});
const result = await response.json();
if (!result.success) {
switch (result.errorCode) {
case "CREDITS_EXHAUSTED":
// Prompt user to upgrade or wait for reset
break;
case "RATE_LIMIT_EXCEEDED":
// Wait and retry after Retry-After header
break;
case "API_KEY_INVALID":
// Re-authenticate
break;
default:
console.error(`API error: ${result.errorCode} — ${result.message}`);
}
}
```
```python Python theme={null}
import requests
response = requests.post(
"https://api.humandesignapi.nl/v2/charts/simple",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY",
"HD-Geocode-Key": "YOUR_GEOCODE_KEY",
},
json={"birthdate": "1990-01-15", "birthtime": "14:30", "location": "Amsterdam"},
)
result = response.json()
if not result["success"]:
error_code = result["errorCode"]
if error_code == "CREDITS_EXHAUSTED":
# Prompt user to upgrade or wait for reset
pass
elif error_code == "RATE_LIMIT_EXCEEDED":
retry_after = response.headers.get("Retry-After", 60)
# Wait retry_after seconds before retrying
pass
else:
print(f"API error: {error_code} — {result['message']}")
```
## HTTP Status Categories
| Status | Meaning | Retry? |
| ------- | -------------------------------------- | ------------------------------------------------------- |
| **400** | Validation error (bad input) | No — fix the request |
| **401** | Authentication failure | No — check your API key |
| **402** | Credits exhausted | No — wait for reset, enable overage, or upgrade |
| **403** | Access denied (wrong tier or inactive) | No — upgrade plan or contact support |
| **429** | Rate limit exceeded | Yes — wait for `Retry-After` seconds |
| **500** | Server error | Yes — retry with backoff, contact support if persistent |
## Retry Strategy
* **Only retry** `429` and `500` errors
* **Never retry** `400`, `401`, `402`, or `403` — these require a change in the request or account
* For `429`, use the `Retry-After` response header (value in seconds)
* For `500`, use exponential backoff (1s, 2s, 4s, max 3 retries)
## Full Error Code Reference
See [Error Codes](/api-reference/error-codes) for the complete list of all error codes with descriptions and recommended actions.
# Plans & Credits
Source: https://docs.humandesignapi.nl/guides/plans-and-credits
Understand API plans, credit allocation, and usage tracking.
Every API call costs 1 credit. Your plan determines how many credits you get each month and which endpoints you can access.
## Plans
| Plan | Access Tier | Monthly Credits | Annual Credits/mo | Rollover Cap | Overage Rate (per 1,000) | Monthly Price | Annual Price | Lifetime Price |
| ------------- | ----------- | --------------- | ----------------- | ------------ | ------------------------ | ------------- | ------------ | -------------- |
| **Hobbyist** | Basic | 5,000 | 6,000 | 10,000 | €2.00 | €22.50 | €225 | — |
| **Developer** | Advanced | 10,000 | 12,000 | 20,000 | €2.00 | €35 | €350 | — |
| **Scale** | Advanced | 50,000 | 60,000 | 100,000 | €1.00 | €47.50 | €475 | — |
| **Lifetime** | Advanced | 50,000 | — | 100,000 | €1.00 | — | — | €1,200 |
## Access Tiers
| Tier | Available Endpoints |
| ------------ | --------------------------------------------------------------------------------- |
| **Basic** | `/v2/charts/simple`, `/v1/bodygraphs/simple` |
| **Advanced** | All endpoints, including `/v2/charts`, `/v2/charts/coordinates`, `/v1/bodygraphs` |
## Credit System
### Monthly Allocation
Credits reset monthly. Annual plans receive 20% more credits per month than the equivalent monthly plan.
### Rollover
Unused credits roll over to the next month, up to your plan's rollover cap. Any excess beyond the cap is lost at reset.
**Example**: Developer plan (10,000/month, 20,000 cap). You use 7,000 credits in March, leaving 3,000 unused. In April you start with 13,000 credits (10,000 new + 3,000 rolled over). If you had 15,000 unused, only 10,000 would roll over (capped at 20,000 total).
### Overage
Overage is **disabled by default**. When enabled:
* Requests beyond your credit limit succeed and are billed at your plan's overage rate per 1,000 API calls
* Overage charges appear on your next invoice via Stripe
When disabled, requests beyond your credit limit return `402` with error code [`CREDITS_EXHAUSTED`](/api-reference/error-codes#billing-errors).
You can enable or disable overage from your [account settings](https://humandesignapi.nl/dashboard/account).
### Cancellation
When you cancel a subscription:
* Your plan remains active until the end of the current billing period
* At the end of the period, credits expire to 0 and no new credits are allocated
# Rate Limiting
Source: https://docs.humandesignapi.nl/guides/rate-limiting
Understand rate limits and how to handle them.
Rate limits protect the API from abuse and ensure fair usage for all consumers.
## Limits
| Scope | Limit | Key |
| ---------------------------------------- | ---------------- | ----------- |
| **Authenticated API** (`/v1/*`, `/v2/*`) | 100 requests/min | Per API key |
## Response When Limited
When you exceed a rate limit, the API returns:
* **HTTP 429** Too Many Requests
* **Error code**: `RATE_LIMIT_EXCEEDED`
* **`Retry-After` header**: number of seconds to wait before retrying
```json theme={null}
{
"timestamp": "2026-03-24T12:00:00.000Z",
"success": false,
"message": "Too many requests. Please try again later.",
"errorCode": "RATE_LIMIT_EXCEEDED",
"type": "",
"data": null
}
```
## Rate Limit Headers
Every response includes standard rate limit headers per the [IETF RateLimit header fields](https://datatracker.ietf.org/doc/draft-ietf-httpapi-ratelimit-headers/09/) specification:
| Header | Description | Example |
| ------------------ | --------------------------------------------------------------------------- | ---------------------------------------------- |
| `ratelimit-policy` | Policy name, quota (`q`), window in seconds (`w`), and partition key (`pk`) | `"100-in-1min"; q=100; w=60; pk=:ZGE1M2Y4...:` |
| `ratelimit` | Policy name, remaining requests (`r`), and seconds until reset (`t`) | `"100-in-1min"; r=99; t=60` |
| `Retry-After` | Seconds to wait before retrying (**only on 429 responses**) | `30` |
## Best Practices
1. **Respect `Retry-After`** — when you receive a 429, wait for the specified number of seconds
2. **Monitor rate limit headers** — parse the `RateLimit` header to check remaining requests and throttle proactively
3. **Use exponential backoff** — if retrying, increase delay: 1s, 2s, 4s
4. **Cache results** — Human Design charts for the same birth data are deterministic. Cache responses to avoid redundant calls
5. **Batch wisely** — if generating multiple charts, space requests evenly rather than bursting
# How to Render Your Own Chart
Source: https://docs.humandesignapi.nl/guides/render-your-own-chart
Turn a Human Design chart into a themed SVG image with one extra field.
The Visual Chart endpoints (`POST /v2/visual-charts` and `POST /v2/visual-charts/coordinates`) return the same chart data as `/v2/charts`, plus an `svgRenderUrl` you can drop straight into an `
` tag.
**Public Beta.** Visual Charts are in Public Beta, open to all Developer plans
and up. Behavior may change before GA. We'd love your feedback:
[info@appdebock.nl](mailto:info@appdebock.nl).
## Why Render a Visual Chart
One request returns the full `ChartResult` you already get from `/v2/charts`, plus a ready-to-embed SVG.
* **Fast, edge-rendered**: rendered at the edge for high performance and low latency
* **Stateless and private**: no PII stored; HMAC-signed render tokens carry only chart activations
* **Drop-in SVG**: an `svgRenderUrl` you style in an `
` tag or CSS `background-image`
* **Your own branding**: create a branded chart style in the template editor
## Request Format
```bash theme={null}
curl -X POST https://api.humandesignapi.nl/v2/visual-charts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "HD-Geocode-Key: YOUR_GEOCODE_KEY" \
-d '{
"birthdate": "1990-01-15",
"birthtime": "14:30",
"location": "Amsterdam, The Netherlands"
}'
```
The request body is identical to `POST /v2/charts`. See the [v2 request format](/api-reference/v2/overview#request-format) for the field table.
Already have latitude and longitude? Use [`POST /v2/visual-charts/coordinates`](/api-reference/visual-charts/generate-a-chart-with-a-rendered-image-from-coordinates) instead. It takes `lat` and `lng` in place of `location`, and needs no geocoding key.
## Response: the `svgRenderUrl` field
`svgRenderUrl` is a **top-level sibling of `data`**, not a field inside it:
```json theme={null}
{
"timestamp": "2026-03-24T12:00:00.000Z",
"success": true,
"message": "Chart generated",
"errorCode": "",
"type": "ChartResult",
"data": {
"type": "Generator",
"profile": "6/2",
"centers": ["G", "Sacral", "Spleen", "Throat"],
"strategy": "To Respond",
"authority": "Sacral",
...
},
"svgRenderUrl": "https://render.appdebock.nl/1f0c8b3a-9d64-4a1e-b0f2-7c5ad2e91b83.svg?t=eyJ..."
}
```
Everything under `data` is the same [`ChartResult`](/response-format#data-types) that `POST /v2/charts` returns.
## Using the Render URL
The URL serves `image/svg+xml`. No client-side JavaScript, no build step.
### As an `
` tag
```html theme={null}
```
### As a CSS background image
```css theme={null}
.chart {
background-image: url("https://render.appdebock.nl/1f0c8b3a-9d64-4a1e-b0f2-7c5ad2e91b83.svg?t=eyJ...");
}
```
The URL is stable and non-expiring, and the render is served with a long-lived immutable cache header, so it is safe to hotlink and safe to cache aggressively.
Want a different look? Build a branded chart style in the [template editor](https://humandesignapi.nl/dashboard/visual-chart). Every Visual Chart you request afterwards renders with that style, and the URL shape stays the same.
## Security & Data Handling
* **Stateless.** All render state travels in the signed URL. Nothing about your request, the render token, or the rendered chart is stored server-side. The edge holds a 24 hour cache of your chart style only.
* **No PII.** The signed token payload is exactly the chart's gate and center activations (`design`, `personality`, `centers`). It carries no name, birthdate, birthtime, location, coordinates, or account id. The template id in the path is an opaque UUID.
* **HMAC-signed.** Tokens are signed with HMAC-SHA-256 and verified at the edge before anything renders. Any edit to the token invalidates the signature and the render is refused.
* **Bearer link.** A render URL is a capability: it does not expire and cannot be revoked. Anyone holding the URL can view that chart's render. Treat it like a secret if the chart should stay private, and do not publish it where you would not publish the activations themselves.
## Access Tier
Visual Charts are available on Developer plans and up (Developer, Scale, and Lifetime). Plans below that receive `403 ACCESS_DENIED`. See [Plans & Credits](/guides/plans-and-credits).
## API Reference
* [`POST /v2/visual-charts`](/api-reference/visual-charts/generate-a-chart-with-a-rendered-image)
* [`POST /v2/visual-charts/coordinates`](/api-reference/visual-charts/generate-a-chart-with-a-rendered-image-from-coordinates)
## Validation Errors
| Error Code | Description |
| ------------------------ | ------------------------------------------------------------------------------------------------- |
| `INVALID_BIRTHDATE` | Birthdate is missing or not in `YYYY-MM-DD` format |
| `INVALID_BIRTHTIME` | Birthtime is missing or not in `HH:MM` format |
| `INVALID_LOCATION` | Location is empty or shorter than 4 characters |
| `INVALID_LATITUDE` | Latitude is missing, not a number, or outside -90 to 90 (`/coordinates` only) |
| `INVALID_LONGITUDE` | Longitude is missing, not a number, or outside -180 to 180 (`/coordinates` only) |
| `TIMEZONE_LOOKUP_FAILED` | Could not determine timezone for the given coordinates (`/coordinates` only) |
| `GEOCODE_KEY_MISSING` | No `HD-Geocode-Key` header on `/v2/visual-charts`. Add the header, or use the coordinates variant |
| `GEOCODE_FAILED` | The location could not be geocoded. Check the geocoding key and the spelling of the location |
See [Error Codes](/api-reference/error-codes) for the full list, including authentication, billing, and rate limit errors.
# Human Design API
Source: https://docs.humandesignapi.nl/index
Generate Human Design personality charts from birth date, time, and location.
The Human Design API calculates complete Human Design charts using precise astronomical calculations. Send birth date, time, and location — get back structured chart data including type, profile, channels, centers, gates, authority, strategy, and more.
Built for developers, AI agents, and no-code platforms.
Make your first API call in under 5 minutes
Set up API key and geocoding key
Explore all v2 endpoints
Integrate with LLMs, agents, and no-code tools
## Key Features
* **Full chart generation** — type, profile, authority, strategy, channels, gates, centers, incarnation cross, activations, and more
* **Simplified chart** — just type, profile, gates, channels, and centers for lightweight integrations
* **Coordinates endpoint** — generate charts from lat/lng without a geocoding key
* **Structured JSON** — consistent response envelope with machine-readable error codes
* **AI-ready** — designed for function calling, tool use, and agent workflows
## Try It First
See the API in action on the [landing page demo](https://humandesignapi.nl/#demo) before signing up.
# Migrating from v1 to v2
Source: https://docs.humandesignapi.nl/migration/v1-to-v2
Step-by-step guide to upgrade from API v1 to v2.
## Why Migrate
* **Standard response envelope** — consistent structure for every response
* **camelCase fields** — follows modern JSON conventions
* **ISO 8601 dates** — `YYYY-MM-DD` instead of `DD-MMM-YY`
* **Machine-readable error codes** — branch on `errorCode` instead of parsing messages
* **New coordinates endpoint** — generate charts from lat/lng without a geocoding key
## Breaking Changes
The authentication header changed between v1 and v2. This is the most common migration issue.
| Aspect | v1 | v2 |
| ------------------ | ------------------------------- | ---------------------------------- |
| **Auth header** | `HD-Api-Key: YOUR_KEY` | `Authorization: Bearer YOUR_KEY` |
| **Date format** | `DD-MMM-YY` (e.g., `15-Jan-90`) | `YYYY-MM-DD` (e.g., `1990-01-15`) |
| **Base path** | `/v1/bodygraphs` | `/v2/charts` |
| **Response** | Flat JSON object | Envelope with `data` field |
| **Field naming** | `snake_case` | `camelCase` |
| **Error handling** | HTTP status only | `errorCode` field in response body |
### Renamed Fields
| v1 (`snake_case`) | v2 (`camelCase`) |
| ------------------- | ------------------ |
| `channels_short` | `channelsShort` |
| `channels_long` | `channelsLong` |
| `incarnation_cross` | `incarnationCross` |
| `not_self_theme` | `notSelfTheme` |
| `north_node` | `northNode` |
| `south_node` | `southNode` |
### Renamed Endpoints
| v1 | v2 |
| ---------------------------- | ----------------------------------- |
| `POST /v1/bodygraphs` | `POST /v2/charts` |
| `POST /v1/bodygraphs/simple` | `POST /v2/charts/simple` |
| — | `POST /v2/charts/coordinates` (new) |
## Step-by-Step Migration
### 1. Update the base URL
```diff theme={null}
- https://api.humandesignapi.nl/v1/bodygraphs
+ https://api.humandesignapi.nl/v2/charts
```
### 2. Change the authentication header
```diff theme={null}
- HD-Api-Key: YOUR_API_KEY
+ Authorization: Bearer YOUR_API_KEY
```
The `HD-Geocode-Key` header remains the same for location-based endpoints.
### 3. Update the date format
```diff theme={null}
- "birthdate": "15-Jan-90"
+ "birthdate": "1990-01-15"
```
### 4. Update response parsing
v2 wraps the chart data in a `data` field:
```diff theme={null}
- const chart = await response.json();
- console.log(chart.type);
+ const result = await response.json();
+ const chart = result.data;
+ console.log(chart.type);
```
Always check `result.success` before accessing `result.data`.
### 5. Update field names to camelCase
```diff theme={null}
- chart.channels_short
+ chart.channelsShort
- chart.incarnation_cross
+ chart.incarnationCross
- chart.not_self_theme
+ chart.notSelfTheme
- chart.activations.design.north_node
+ chart.activations.design.northNode
```
## Complete Before and After
```bash v1 theme={null}
curl -X POST https://api.humandesignapi.nl/v1/bodygraphs/simple \
-H "Content-Type: application/json" \
-H "HD-Api-Key: YOUR_API_KEY" \
-H "HD-Geocode-Key: YOUR_GEOCODE_KEY" \
-d '{
"birthdate": "15-Jan-90",
"birthtime": "14:30",
"location": "Amsterdam, The Netherlands"
}'
```
```bash v2 theme={null}
curl -X POST https://api.humandesignapi.nl/v2/charts/simple \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "HD-Geocode-Key: YOUR_GEOCODE_KEY" \
-d '{
"birthdate": "1990-01-15",
"birthtime": "14:30",
"location": "Amsterdam, The Netherlands"
}'
```
## FAQ
### Do I need a new API key?
No. The same API key works for both v1 and v2 — only the header name changes.
### Is v1 being deprecated?
v1 remains available with no planned sunset. However, new features (like the coordinates endpoint) are v2 only.
### Can I use v1 and v2 simultaneously?
Yes. Both versions share the same API key and credit pool. You can migrate endpoints incrementally.
# Quick Start
Source: https://docs.humandesignapi.nl/quickstart
Make your first API call in under 5 minutes.
## 1. Get Your API Key
Sign up at [humandesignapi.nl](https://humandesignapi.nl) and choose a plan. Your API key will be available in the [dashboard](https://humandesignapi.nl/dashboard).
## 2. Get a Google Geocoding Key
The location-based endpoints use Google Geocoding to convert place names into coordinates. You need a [Google Geocoding API key](https://developers.google.com/maps/documentation/geocoding/get-api-key).
Don't want a geocoding key? Use the [coordinates endpoint](/guides/coordinates-endpoint) instead — pass `lat` and `lng` directly.
## 3. Make Your First Request
```bash cURL theme={null}
curl -X POST https://api.humandesignapi.nl/v2/charts/simple \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "HD-Geocode-Key: YOUR_GEOCODE_KEY" \
-d '{
"birthdate": "1990-01-15",
"birthtime": "14:30",
"location": "Amsterdam, The Netherlands"
}'
```
```javascript JavaScript theme={null}
const response = await fetch("https://api.humandesignapi.nl/v2/charts/simple", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY",
"HD-Geocode-Key": "YOUR_GEOCODE_KEY",
},
body: JSON.stringify({
birthdate: "1990-01-15",
birthtime: "14:30",
location: "Amsterdam, The Netherlands",
}),
});
const data = await response.json();
console.log(data);
```
```python Python theme={null}
import requests
response = requests.post(
"https://api.humandesignapi.nl/v2/charts/simple",
headers={
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY",
"HD-Geocode-Key": "YOUR_GEOCODE_KEY",
},
json={
"birthdate": "1990-01-15",
"birthtime": "14:30",
"location": "Amsterdam, The Netherlands",
},
)
data = response.json()
print(data)
```
## 4. Understand the Response
All v2 responses use a [standard envelope](/response-format):
```json theme={null}
{
"timestamp": "2026-03-24T12:00:00.000Z",
"success": true,
"message": "Chart generated",
"errorCode": "",
"type": "ChartSimpleResult",
"data": {
"type": "Generator",
"profile": "6/2",
"gates": ["20", "34", "10", "57"],
"channelsShort": ["20-34", "10-57"],
"centers": ["G", "Sacral", "Spleen", "Throat"]
}
}
```
| Field | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------------- |
| `timestamp` | ISO 8601 timestamp of the response |
| `success` | `true` if the request succeeded |
| `message` | Human-readable status message |
| `errorCode` | Machine-readable [error code](/api-reference/error-codes) (empty on success) |
| `type` | Data type name ([`ChartSimpleResult`](/response-format#data-types) or [`ChartResult`](/response-format#data-types)) |
| `data` | The chart data |
## Next Steps
Deep dive into API key and geocoding key setup
Get the complete chart with all properties
Understand the standard response envelope
Handle errors gracefully
# Response Format
Source: https://docs.humandesignapi.nl/response-format
The standard response envelope used by all v2 endpoints.
All v2 endpoints return a consistent JSON envelope. This makes parsing predictable — every response has the same top-level structure regardless of success or failure.
## Envelope Fields
| Field | Type | Description |
| ----------- | -------------- | ---------------------------------------------------------------------------------------- |
| `timestamp` | string | ISO 8601 timestamp of response generation |
| `success` | boolean | `true` if the request succeeded, `false` on error |
| `message` | string | Human-readable status message |
| `errorCode` | string | Machine-readable [error code](/api-reference/error-codes) — empty string `""` on success |
| `type` | string | Data type name of the object in `data` — empty string `""` on error |
| `data` | object \| null | The response payload — `null` on error |
## Success Response
```json theme={null}
{
"timestamp": "2026-03-24T12:00:00.000Z",
"success": true,
"message": "Chart generated",
"errorCode": "",
"type": "ChartSimpleResult",
"data": {
"type": "Generator",
"profile": "6/2",
"gates": ["20", "34", "10", "57"],
"channelsShort": ["20-34", "10-57"],
"centers": ["G", "Sacral", "Spleen", "Throat"]
}
}
```
## Error Response
```json theme={null}
{
"timestamp": "2026-03-24T12:00:01.000Z",
"success": false,
"message": "Birthdate must be in YYYY-MM-DD format",
"errorCode": "INVALID_BIRTHDATE",
"type": "",
"data": null
}
```
## Data Types
The `type` field tells you what shape the `data` object has:
| Type Value | Returned By | Description |
| ------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `ChartResult` | `/v2/charts`, `/v2/charts/coordinates` | Full chart with all properties (type, profile, channels, centers, strategy, authority, incarnation cross, activations, and more) |
| `ChartSimpleResult` | `/v2/charts/simple` | Simplified chart (type, profile, gates, channels, centers) |
## Parsing Guidelines
1. **Check `success` first** — determines whether `data` is populated or `null`
2. **Use `errorCode` for logic** — never parse `message` for error handling. Messages are human-readable and may change without notice.
3. **`data` is always a single object** — v2 chart endpoints return one chart per request, never an array
## v1 Response Format
v1 endpoints return the chart data directly as a flat JSON object — no envelope. Field names use `snake_case` (e.g., `channels_short`, `incarnation_cross`). See the [migration guide](/migration/v1-to-v2) for differences.