Base URLs
All API requests are made to one of the following base URLs depending on your environment:
| Environment | Base URL |
|---|
| Production | https://api.appdna.ai |
| Sandbox | https://sandbox-api.appdna.ai |
Never use production API keys in sandbox or development environments. Use the sandbox base URL with test keys during development.
API Key Types
AppDNA uses two distinct key types, each designed for a different integration surface.
1. SDK API Keys
SDK API Keys authenticate mobile SDKs (iOS, Android, Flutter, React Native) against the ingestion and config-bundle endpoints. They are stored in the sdk_api_keys table.
| Field | Description |
|---|
public_key | Unique public identifier, prefixed adn_live_ (production) or adn_test_ (sandbox) |
secret_key_hash | Hashed secret counterpart |
environment | production or sandbox |
status | active or revoked |
Send the public key in the x-api-key header:
curl -X POST https://api.appdna.ai/api/v1/ingest/events \
-H "Content-Type: application/json" \
-H "x-api-key: adn_live_pk_abc123def456" \
-d '{ ... }'
2. Dashboard API Keys
Dashboard API Keys authenticate server-to-server REST API calls. They are stored in the api_keys table.
| Field | Description |
|---|
key_prefix | Prefix for quick identification |
key_hash | bcrypt hash of the full key |
last_four | Last four characters displayed in the console |
environment | production or sandbox |
permissions | Object with granular permission flags |
expires_at | Optional expiration timestamp |
is_active | Whether the key is currently active |
Permissions object:
{
"track_events": true,
"read_config": true,
"manage_users": false,
"export_data": true
}
Send the key in the Authorization header as a Bearer token:
curl https://api.appdna.ai/api/v1/analytics/kpis \
-H "Authorization: Bearer adn_live_sk_xyz789" \
-H "Content-Type: application/json"
Authentication Levels
AppDNA enforces four authentication levels depending on the endpoint:
Public
No authentication required. Used for health checks and public endpoints.
| Endpoint | Purpose |
|---|
GET /api/v1/ingest/health | Ingestion health check |
GET /api/v1/auth/signup-enabled | Check if signup is enabled |
POST /api/v1/auth/login | User login |
POST /api/v1/auth/signup | User registration |
SDK Key
Requires the x-api-key header. Resolves the key to an app_id and tenant_id pair. Used by the mobile SDKs.
| Endpoint | Purpose |
|---|
GET /api/v1/sdk/bootstrap | SDK bootstrap |
POST /api/v1/ingest/events | Event ingestion |
GET /api/v1/sdk/config-bundle | Download config bundle |
GET /api/v1/sdk/config-bundle/version | Check bundle version |
Customer (JWT)
Requires a valid Firebase JWT. The server calls getAuthContext(req) which resolves to:
{
tenantId: string; // Organization ID
appId: string; // Application ID
userId: string; // Authenticated user ID
role: 'admin' | 'editor' | 'viewer';
}
Used by all dashboard API endpoints (analytics, webhooks, settings, etc.).
Super Admin
Requires a valid JWT with the isSuperAdmin flag. The server calls getTokenUser(req) and verifies the super admin claim. Used exclusively for /admin/* endpoints (tenant management, platform billing, etc.).
Super Admin endpoints are not available to regular API consumers. They are reserved for platform operators.
Managing API Keys
API keys are managed from the AppDNA Console:
- Navigate to Settings in the left sidebar
- Select the SDK tab
- Click API Keys
- Use Create Key to generate a new key pair
When you create a new SDK API Key, the secret key is shown only once. Store it securely — you will not be able to retrieve it again.
Rotating Keys
To rotate a Dashboard API Key:
POST /api/v1/sdk/api-keys/{id}/rotate
This generates a new key and invalidates the previous one. Allow a brief overlap period in your deployment to avoid downtime.
Rate Limits
Rate limits are configurable per application via the app_settings.rate_limit_events_per_min field.
| Setting | Default | Description |
|---|
rate_limit_events_per_min | Configurable | Maximum number of events accepted per minute per app |
When the rate limit is exceeded, the API responds with HTTP 429 Too Many Requests. The SDK automatically retries with exponential backoff.
You have successfully configured authentication when your SDK can call the bootstrap endpoint and receive a valid response with your orgId and appId.