Authentication

All HippoDid API endpoints require authentication.

Table of contents
  1. API Keys (recommended for server-to-server)
  2. JWT Authentication (for browser apps)
  3. Spring Security integration
    1. WebClient with API key (server-to-server)
    2. RestClient with API key
    3. Handling 401 and 403
  4. Rate limit headers
    1. Handling 429 Too Many Requests

The simplest authentication method. Issue an API key from the HippoDid dashboard and include it as a Bearer token.

curl https://api.hippodid.com/v1/characters \
  -H "Authorization: Bearer hd_key_YOUR_KEY_HERE"

API keys are scoped to your tenant. All keys from the same tenant share the same rate limits and character access.

Tier Max API keys
FREE 1
STARTER 1
DEVELOPER 3
BUSINESS 10

API keys are secrets. Never commit them to source control. Use environment variables or a secrets manager.


JWT Authentication (for browser apps)

For browser-based applications, authenticate users via Clerk. The Clerk organization ID maps to a HippoDid tenant, and the user ID maps to a tenant member.

# Exchange a Clerk session token for a JWT, then use it as a Bearer token
curl https://api.hippodid.com/v1/characters \
  -H "Authorization: Bearer eyJhbGciOiJS..."

Clerk → HippoDid mapping:

Clerk concept HippoDid concept
Organization ID (org_...) Tenant ID
User ID (user_...) Member ID
Organization role (org:admin) ADMIN member role
Organization role (org:member) MEMBER member role

Member roles and permissions:

Role Permissions
OWNER Full access, billing, member management
ADMIN Manage characters and memories for all members
MEMBER Manage own characters and memories
VIEWER Read-only access (Developer+ tier)

Spring Security integration

WebClient with API key (server-to-server)

import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class HippoDidClientConfig {

    @Value("${hippodid.api-key}")
    private String apiKey;

    @Bean
    public WebClient hippoDidClient() {
        return WebClient.builder()
            .baseUrl("https://api.hippodid.com")
            .defaultHeader("Authorization", "Bearer " + apiKey)
            .build();
    }
}

RestClient with API key

import org.springframework.web.client.RestClient;

@Bean
public RestClient hippoDidRestClient(@Value("${hippodid.api-key}") String apiKey) {
    return RestClient.builder()
        .baseUrl("https://api.hippodid.com")
        .defaultHeader("Authorization", "Bearer " + apiKey)
        .build();
}

Handling 401 and 403

var response = restClient.post()
    .uri("/v1/characters/{id}/memories", characterId)
    .body(request)
    .retrieve()
    .onStatus(status -> status.value() == 401, (req, res) -> {
        throw new RuntimeException("Invalid or expired API key");
    })
    .onStatus(status -> status.value() == 403, (req, res) -> {
        throw new RuntimeException("Access denied — check member role and tier");
    })
    .body(MemoryResponse.class);

Rate limit headers

Every API response includes rate limit information in the response headers.

Header Description
X-RateLimit-Limit Maximum requests allowed in the current window (per minute)
X-RateLimit-Remaining Requests remaining in the current window
X-RateLimit-Reset Unix timestamp (seconds) when the window resets
X-RateLimit-Bucket The rate limit bucket for this request: SEARCH, WRITE, SYNC, MANAGEMENT, or AI_PROXY

Example response headers:

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 28
X-RateLimit-Reset: 1705312260
X-RateLimit-Bucket: WRITE

Handling 429 Too Many Requests

var response = restClient.post()
    .uri("/v1/characters/{id}/memories", characterId)
    .body(request)
    .retrieve()
    .onStatus(status -> status.value() == 429, (req, res) -> {
        String resetHeader = res.getHeaders().getFirst("X-RateLimit-Reset");
        long resetAt = Long.parseLong(resetHeader != null ? resetHeader : "0");
        long waitMs = (resetAt * 1000L) - System.currentTimeMillis();
        throw new RateLimitException("Rate limit exceeded, retry after " + waitMs + "ms");
    })
    .body(MemoryResponse.class);

For details on per-tier rate limits and bucket definitions, see Tiers & Limits.


Copyright © 2024 HippoDid. Distributed under the MIT License.

This site uses Just the Docs, a documentation theme for Jekyll.