">

API Documentation

Everything you need to integrate Digital Tap AI into your infrastructure. Manage clusters, automate optimization, and track savings programmatically.

https://digitaltap.ai/api

🔐 Authentication

Digital Tap AI supports two authentication methods. Use whichever fits your workflow:

Bearer Token (JWT)

Returned from /v1/auth/login. Short-lived, ideal for user sessions and interactive use.

Authorization: Bearer eyJhbG...

API Key

Also returned from /v1/auth/login. Long-lived, ideal for CI/CD pipelines and server-to-server integrations.

X-API-Key: dtap_live_abc123...

⚠️ Keep Your Keys Safe

Never commit API keys to version control. Use environment variables or a secrets manager.

All API responses follow a consistent format:

{
  "success": true,
  "data": { ... },
  "meta": { "request_id": "req_abc123", "timestamp": "2026-03-03T21:00:00Z" }
}

Errors return:

{
  "success": false,
  "error": { "code": "UNAUTHORIZED", "message": "Invalid or expired token" }
}

🚀 Quick Start

Create an Account

Register via the API or at digitaltap.ai/auth

Get Your API Key

Log in to receive your JWT token and long-lived API key.

Connect a Platform

Add your Databricks, EMR, Synapse, or Dataproc credentials.

Start Optimizing

Run analysis, set up schedules, and watch your savings grow.

Auth Endpoints

POST /v1/auth/register Create account

Register a new user account and organization.

ParameterTypeRequiredDescription
namestringrequiredFull name
emailstringrequiredEmail address
passwordstringrequiredMin 8 characters
companystringoptionalCompany name
org_namestringoptionalOrganization name
curl -X POST https://digitaltap.ai/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Smith",
    "email": "jane@acme.com",
    "password": "securepass123",
    "company": "Acme Corp",
    "org_name": "acme-engineering"
  }'
import requests

resp = requests.post(
    "https://digitaltap.ai/api/auth/register",
    json={
        "name": "Jane Smith",
        "email": "jane@acme.com",
        "password": "securepass123",
        "company": "Acme Corp",
        "org_name": "acme-engineering"
    }
)
print(resp.json())
const resp = await fetch(
  "https://digitaltap.ai/api/auth/register",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      name: "Jane Smith",
      email: "jane@acme.com",
      password: "securepass123",
      company: "Acme Corp",
      org_name: "acme-engineering"
    })
  }
);
const data = await resp.json();
console.log(data);
Response 201 Created
{
  "success": true,
  "data": {
    "id": "usr_a1b2c3",
    "name": "Jane Smith",
    "email": "jane@acme.com",
    "org": { "slug": "acme-engineering", "role": "owner" }
  }
}
POST /v1/auth/login Sign in → JWT + API key
ParameterTypeRequiredDescription
emailstringrequiredEmail address
passwordstringrequiredPassword
curl -X POST https://digitaltap.ai/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "jane@acme.com", "password": "securepass123"}'
resp = requests.post(
    "https://digitaltap.ai/api/auth/login",
    json={"email": "jane@acme.com", "password": "securepass123"}
)
tokens = resp.json()["data"]
print(tokens["token"], tokens["api_key"])
const { data } = await fetch(
  "https://digitaltap.ai/api/auth/login",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ email: "jane@acme.com", password: "securepass123" })
  }
).then(r => r.json());
console.log(data.token, data.api_key);
Response 200 OK
{
  "success": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "api_key": "dtap_live_k8x9m2...",
    "expires_in": 3600
  }
}
POST /v1/auth/reset-password Password reset
ParameterTypeRequiredDescription
emailstringrequiredAccount email
Response 200 OK
{
  "success": true,
  "data": { "message": "Password reset email sent" }
}

Account Endpoints

GET /v1/account Account details

Returns the authenticated user's account information.

Response 200 OK
{
  "success": true,
  "data": {
    "id": "usr_a1b2c3",
    "name": "Jane Smith",
    "email": "jane@acme.com",
    "plan": "growth",
    "clusters_managed": 12,
    "created_at": "2026-01-15T10:30:00Z"
  }
}
GET /v1/account/usage Usage reports
Response 200 OK
{
  "success": true,
  "data": {
    "period": "2026-03",
    "api_calls": 14523,
    "clusters_optimized": 8,
    "hibernations_triggered": 342
  }
}
GET /v1/account/billing Billing history
Response 200 OK
{
  "success": true,
  "data": {
    "plan": "growth",
    "monthly_cost": 499,
    "invoices": [
      { "date": "2026-02-01", "amount": 499, "status": "paid" }
    ]
  }
}
GET /v1/account/savings Total savings summary
Response 200 OK
{
  "success": true,
  "data": {
    "total_saved_usd": 28450.00,
    "water_saved_gallons": 125000,
    "idle_hours_eliminated": 4200,
    "co2_reduced_kg": 1850
  }
}
GET /v1/account/alerts Alert feed
Response 200 OK
{
  "success": true,
  "data": [
    {
      "id": "alt_x1",
      "type": "idle_cluster",
      "message": "Cluster prod-etl idle for 45 minutes",
      "severity": "warning",
      "created_at": "2026-03-03T14:22:00Z"
    }
  ]
}

Platform Endpoints

POST /v1/platforms Connect a platform
ParameterTypeRequiredDescription
typestringrequireddatabricks | emr | synapse | dataproc
namestringrequiredDisplay name
credentialsobjectrequiredPlatform-specific credentials
regionstringoptionalCloud region
curl -X POST https://digitaltap.ai/api/platforms \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "databricks",
    "name": "Production Databricks",
    "credentials": {
      "workspace_url": "https://dbc-abc123.cloud.databricks.com",
      "token": "dapi_xyz789..."
    },
    "region": "us-east-1"
  }'
resp = requests.post(
    "https://digitaltap.ai/api/platforms",
    headers={"Authorization": f"Bearer {token}"},
    json={
        "type": "databricks",
        "name": "Production Databricks",
        "credentials": {
            "workspace_url": "https://dbc-abc123.cloud.databricks.com",
            "token": "dapi_xyz789..."
        }
    }
)
const resp = await fetch(
  "https://digitaltap.ai/api/platforms",
  {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      type: "databricks",
      name: "Production Databricks",
      credentials: {
        workspace_url: "https://dbc-abc123.cloud.databricks.com",
        token: "dapi_xyz789..."
      }
    })
  }
);
Response 201 Created
{
  "success": true,
  "data": {
    "id": "plat_d4e5f6",
    "type": "databricks",
    "name": "Production Databricks",
    "status": "connected",
    "clusters_discovered": 7
  }
}
GET /v1/platforms List connected platforms
Response 200 OK
{
  "success": true,
  "data": [
    { "id": "plat_d4e5f6", "type": "databricks", "name": "Production Databricks", "status": "connected" },
    { "id": "plat_g7h8i9", "type": "emr", "name": "AWS EMR Staging", "status": "connected" }
  ]
}
PUT /v1/platforms/{id} Update platform
ParameterTypeRequiredDescription
namestringoptionalNew display name
credentialsobjectoptionalUpdated credentials
Response 200 OK
{ "success": true, "data": { "id": "plat_d4e5f6", "name": "Prod DB Updated", "status": "connected" } }
DELETE /v1/platforms/{id} Remove platform
Response 200 OK
{ "success": true, "data": { "message": "Platform removed" } }
POST /v1/platforms/{id}/test Test connectivity
Response 200 OK
{
  "success": true,
  "data": { "reachable": true, "latency_ms": 142, "permissions": ["read", "write", "admin"] }
}

Cluster Endpoints

GET /v1/clusters List all clusters

Returns clusters across all connected platforms.

curl https://digitaltap.ai/api/clusters \
  -H "X-API-Key: dtap_live_k8x9m2..."
resp = requests.get(
    "https://digitaltap.ai/api/clusters",
    headers={"X-API-Key": "dtap_live_k8x9m2..."}
)
const resp = await fetch(
  "https://digitaltap.ai/api/clusters",
  { headers: { "X-API-Key": "dtap_live_k8x9m2..." } }
);
Response 200 OK
{
  "success": true,
  "data": [
    {
      "platform": "databricks",
      "cluster_id": "0301-prod-etl",
      "name": "Production ETL",
      "state": "running",
      "idle_minutes": 0,
      "hourly_cost": 12.50,
      "nodes": 8
    },
    {
      "platform": "emr",
      "cluster_id": "j-2ABC3DEF",
      "name": "Staging Analytics",
      "state": "idle",
      "idle_minutes": 47,
      "hourly_cost": 8.20,
      "nodes": 4
    }
  ]
}
GET /v1/clusters/{platform}/{cluster_id} Cluster details
Response 200 OK
{
  "success": true,
  "data": {
    "platform": "databricks",
    "cluster_id": "0301-prod-etl",
    "name": "Production ETL",
    "state": "running",
    "instance_type": "i3.xlarge",
    "nodes": 8,
    "uptime_hours": 6.5,
    "cost_today": 81.25,
    "water_usage_gallons": 18.4
  }
}
POST /v1/clusters/{platform}/{cluster_id}/hibernate Hibernate cluster

Hibernates a cluster with state preservation for fast resume.

Response 200 OK
{
  "success": true,
  "data": {
    "cluster_id": "0301-prod-etl",
    "previous_state": "idle",
    "new_state": "hibernating",
    "estimated_savings_per_hour": 12.50
  }
}
POST /v1/clusters/{platform}/{cluster_id}/resume Resume cluster
Response 200 OK
{
  "success": true,
  "data": {
    "cluster_id": "0301-prod-etl",
    "new_state": "resuming",
    "estimated_ready_seconds": 45
  }
}
POST /v1/clusters/analyze Run optimization analysis

Analyzes all connected clusters and returns optimization opportunities.

Response 200 OK
{
  "success": true,
  "data": {
    "total_clusters": 12,
    "idle_clusters": 4,
    "potential_savings_monthly": 3420.00,
    "recommendations": 7
  }
}
POST /v1/clusters/optimize Execute optimization
ParameterTypeRequiredDescription
idle_threshold_minutesintegeroptionalMinutes idle before action (default: 30)
dry_runbooleanoptionalPreview only, no changes (default: false)
curl -X POST https://digitaltap.ai/api/clusters/optimize \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"idle_threshold_minutes": 20, "dry_run": true}'
resp = requests.post(
    "https://digitaltap.ai/api/clusters/optimize",
    headers={"Authorization": f"Bearer {token}"},
    json={"idle_threshold_minutes": 20, "dry_run": True}
)
const resp = await fetch(
  "https://digitaltap.ai/api/clusters/optimize",
  {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${token}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ idle_threshold_minutes: 20, dry_run: true })
  }
);
Response 200 OK
{
  "success": true,
  "data": {
    "dry_run": true,
    "actions": [
      { "cluster": "j-2ABC3DEF", "action": "hibernate", "reason": "Idle 47 min", "savings_per_hour": 8.20 }
    ],
    "total_hourly_savings": 8.20
  }
}

Scheduling Endpoints

POST /v1/schedules Create schedule rule
ParameterTypeRequiredDescription
namestringrequiredSchedule name
typestringrequiredtime | idle | cost
cluster_idsstring[]requiredTarget clusters
actionstringrequiredhibernate | resume | resize
cronstringoptionalCron expression (for time type)
thresholdobjectoptionalThreshold config (for idle/cost type)
Response 201 Created
{
  "success": true,
  "data": {
    "id": "sch_m1n2",
    "name": "Night Hibernate",
    "type": "time",
    "cron": "0 22 * * 1-5",
    "action": "hibernate",
    "enabled": true
  }
}
GET /v1/schedules List schedules
Response 200 OK
{ "success": true, "data": [{ "id": "sch_m1n2", "name": "Night Hibernate", "type": "time", "enabled": true }] }
PUT /v1/schedules/{id} Update schedule
Response 200 OK
{ "success": true, "data": { "id": "sch_m1n2", "updated": true } }
DELETE /v1/schedules/{id} Delete schedule
Response 200 OK
{ "success": true, "data": { "message": "Schedule deleted" } }
POST /v1/schedules/{id}/run Manual trigger
Response 200 OK
{
  "success": true,
  "data": { "execution_id": "exec_p3q4", "status": "running" }
}

Warm Pool Endpoints

POST /v1/warm-pools Configure warm pool
ParameterTypeRequiredDescription
platform_idstringrequiredPlatform to pool
min_nodesintegerrequiredMinimum warm nodes
max_nodesintegerrequiredMaximum warm nodes
instance_typestringrequiredInstance type
Response 201 Created
{
  "success": true,
  "data": { "id": "wp_r5s6", "min_nodes": 2, "max_nodes": 10, "status": "provisioning" }
}
GET /v1/warm-pools List configs
Response 200 OK
{ "success": true, "data": [{ "id": "wp_r5s6", "min_nodes": 2, "max_nodes": 10, "status": "ready" }] }
GET /v1/warm-pools/status Pool status
Response 200 OK
{
  "success": true,
  "data": {
    "total_warm_nodes": 6,
    "available": 4,
    "in_use": 2,
    "avg_claim_time_seconds": 12
  }
}

Insight Endpoints

GET /v1/clusters/predictions Predicted cluster needs (24h)
Response 200 OK
{
  "success": true,
  "data": {
    "horizon": "24h",
    "predictions": [
      { "cluster_id": "0301-prod-etl", "predicted_usage": "high", "confidence": 0.92, "peak_hour": 14 }
    ]
  }
}
GET /v1/clusters/{platform}/{id}/recommendations Per-cluster recommendations
Response 200 OK
{
  "success": true,
  "data": [
    { "type": "downsize", "detail": "Reduce from 8 to 5 nodes during off-peak", "savings_monthly": 540.00 },
    { "type": "spot_mix", "detail": "Use 60% spot instances for worker nodes", "savings_monthly": 890.00 }
  ]
}
GET /v1/insights Cross-platform insights
Response 200 OK
{
  "success": true,
  "data": {
    "total_waste_monthly": 4200.00,
    "optimization_score": 72,
    "top_opportunity": "Hibernate 3 idle EMR clusters to save $1,800/mo"
  }
}
GET /v1/insights/rightsizing Right-sizing recommendations
Response 200 OK
{
  "success": true,
  "data": [
    {
      "cluster_id": "0301-prod-etl",
      "current_type": "i3.2xlarge",
      "recommended_type": "i3.xlarge",
      "avg_cpu_utilization": 0.23,
      "savings_monthly": 620.00
    }
  ]
}

Notification Endpoints

POST /v1/notifications/channels Add notification channel
ParameterTypeRequiredDescription
typestringrequiredslack | teams | pagerduty | email
configobjectrequiredChannel-specific config (webhook_url, email, etc.)
eventsstring[]optionalEvents to subscribe to
Response 201 Created
{
  "success": true,
  "data": { "id": "nch_t7u8", "type": "slack", "status": "active" }
}
GET /v1/notifications/channels List channels
Response 200 OK
{ "success": true, "data": [{ "id": "nch_t7u8", "type": "slack", "status": "active" }] }
POST /v1/notifications/test Test notification
ParameterTypeRequiredDescription
channel_idstringrequiredChannel to test
Response 200 OK
{ "success": true, "data": { "delivered": true } }

Organization Endpoints

POST /v1/orgs Create org
ParameterTypeRequiredDescription
namestringrequiredOrganization name
slugstringoptionalURL slug (auto-generated if omitted)
Response 201 Created
{
  "success": true,
  "data": { "slug": "acme-engineering", "name": "Acme Engineering", "members": 1 }
}
GET /v1/orgs List user's orgs
Response 200 OK
{ "success": true, "data": [{ "slug": "acme-engineering", "name": "Acme Engineering", "role": "owner" }] }
POST /v1/orgs/{slug}/invite Invite member
ParameterTypeRequiredDescription
emailstringrequiredInvitee email
rolestringoptionaladmin | member | viewer (default: member)
Response 200 OK
{ "success": true, "data": { "invite_id": "inv_v9w0", "email": "bob@acme.com", "status": "pending" } }
GET /v1/orgs/{slug}/members List members
Response 200 OK
{
  "success": true,
  "data": [
    { "id": "usr_a1b2c3", "name": "Jane Smith", "role": "owner" },
    { "id": "usr_d4e5f6", "name": "Bob Chen", "role": "member" }
  ]
}

Monitoring Endpoints

GET /v1/monitoring/status Get monitoring status

Returns current monitoring status including connected platforms, clusters monitored, and recent action count.

Response 200 OK
{
  "enabled": true,
  "platforms_connected": 3,
  "clusters_monitored": 12,
  "actions_last_24h": 7,
  "config": {
    "scan_interval_minutes": 10,
    "idle_threshold_pct": 15.0,
    "idle_threshold_minutes": 30,
    "auto_hibernate": false,
    "auto_rightsize": false,
    "auto_spot_failover": false
  }
}
PUT /v1/monitoring/config Update monitoring config

Update monitoring preferences. All fields are optional — only provided fields are updated.

curl -X PUT https://digitaltap.ai/api/monitoring/config \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "auto_hibernate": true,
    "idle_threshold_minutes": 20,
    "scan_interval_minutes": 5
  }'
import requests

resp = requests.put(
    "https://digitaltap.ai/api/monitoring/config",
    headers={"Authorization": "Bearer YOUR_TOKEN"},
    json={
        "auto_hibernate": True,
        "idle_threshold_minutes": 20,
        "scan_interval_minutes": 5,
    },
)
print(resp.json())
const resp = await fetch("https://digitaltap.ai/api/monitoring/config", {
  method: "PUT",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    auto_hibernate: true,
    idle_threshold_minutes: 20,
    scan_interval_minutes: 5,
  }),
});
console.log(await resp.json());
FieldTypeDescription
scan_interval_minutesintHow often to scan clusters (min: 1)
idle_threshold_pctfloatCPU % below which a cluster is considered idle
idle_threshold_minutesintMinutes idle before action is taken
auto_hibernateboolAutomatically hibernate idle clusters
auto_rightsizeboolAutomatically apply right-sizing recommendations
auto_spot_failoverboolAutomatically failover to spot instances
exclude_clustersstring[]Cluster IDs to exclude from automation
GET /v1/monitoring/actions List optimization actions

Get history of automated optimization actions. Supports pagination and filtering by action type.

ParamTypeDescription
limitintResults per page (1-200, default 50)
offsetintPagination offset
action_typestringFilter: hibernate, rightsize, spot_failover
Response 200 OK
{
  "actions": [
    {
      "id": "act_a1b2c3",
      "platform_type": "databricks",
      "cluster_id": "0123-456789-abc",
      "action_type": "hibernate",
      "status": "completed",
      "reason": "Idle for 45 minutes (CPU < 5%)",
      "savings_usd": 3.20,
      "created_at": "2026-03-12T14:30:00Z"
    }
  ],
  "limit": 50,
  "offset": 0
}
GET /v1/monitoring/metrics/{cluster_id} Cluster utilization history

Get CPU, memory, worker count, and cost history for a specific cluster. Default: 24 hours, max: 168 hours.

ParamTypeDescription
hoursintLookback window (1-168, default 24)
Response 200 OK
{
  "cluster_id": "0123-456789-abc",
  "hours": 24,
  "data_points": 144,
  "metrics": [
    {
      "timestamp": "2026-03-12T00:00:00Z",
      "cpu_util": 12.5,
      "memory_util": 34.2,
      "workers": 4,
      "idle_minutes": 0,
      "cost_per_hour": 2.40,
      "status": "running"
    }
  ]
}
POST /v1/monitoring/pause Pause all monitoring

Emergency stop — pauses all automated monitoring and optimization for your account. No clusters will be touched until resumed.

Response 200 OK
{ "message": "Monitoring paused", "enabled": false }
POST /v1/monitoring/resume Resume monitoring

Re-enable automated monitoring and optimization after a pause.

Response 200 OK
{ "message": "Monitoring resumed", "enabled": true }

⚡ Rate Limiting

API requests are rate-limited to ensure fair usage and platform stability.

TierLimitWindowAuth endpoints
Starter60 requestsPer minute10/min
Growth300 requestsPer minute30/min
Enterprise1,000 requestsPer minute100/min

Rate limit headers are included in every response:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1710273600
X-Request-ID: a1b2c3d4

When rate-limited, you'll receive a 429 Too Many Requests response. Back off and retry after the reset time.

🚨 Error Codes

All errors follow a consistent format:

{
  "error": "Human-readable error message",
  "request_id": "a1b2c3d4"
}
CodeMeaningCommon Causes
400Bad RequestInvalid JSON, missing required fields, validation error
401UnauthorizedMissing/invalid token, expired JWT, bad API key
403ForbiddenInsufficient role/permissions for this action
404Not FoundResource doesn't exist or belongs to another account
409ConflictEmail already registered, slug already taken
429Too Many RequestsRate limit exceeded — see headers for reset time
502Bad GatewayUpstream platform API error (Databricks, EMR, etc.)
500Internal Server ErrorUnexpected error — includes request_id for support

Always include the X-Request-ID header value when contacting support about errors.

© 2026 Digital Tap AI. All rights reserved.

Home Terms Privacy Contact