Skip to main content

Base URLs

All API requests are made to one of the following base URLs depending on your environment:
EnvironmentBase URL
Productionhttps://api.appdna.ai
Sandboxhttps://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.
FieldDescription
public_keyUnique public identifier, prefixed adn_live_ (production) or adn_test_ (sandbox)
secret_key_hashHashed secret counterpart
environmentproduction or sandbox
statusactive 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.
FieldDescription
key_prefixPrefix for quick identification
key_hashbcrypt hash of the full key
last_fourLast four characters displayed in the console
environmentproduction or sandbox
permissionsObject with granular permission flags
expires_atOptional expiration timestamp
is_activeWhether 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.
EndpointPurpose
GET /api/v1/ingest/healthIngestion health check
GET /api/v1/auth/signup-enabledCheck if signup is enabled
POST /api/v1/auth/loginUser login
POST /api/v1/auth/signupUser 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.
EndpointPurpose
GET /api/v1/sdk/bootstrapSDK bootstrap
POST /api/v1/ingest/eventsEvent ingestion
GET /api/v1/sdk/config-bundleDownload config bundle
GET /api/v1/sdk/config-bundle/versionCheck 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:
  1. Navigate to Settings in the left sidebar
  2. Select the SDK tab
  3. Click API Keys
  4. 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.
SettingDefaultDescription
rate_limit_events_per_minConfigurableMaximum 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.