Drippay Workflows API

Define workflow templates for agent execution.

OpenAPI Specification

drippay-workflows-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Drip BillableMetrics Workflows API
  description: "\n# Drip API\n\n**Usage-based billing + execution ledger.**\n\n---\n\n## 60-Second Quickstart (Core SDK)\n\n### 1. Install\n\n```bash\nnpm install @drip-sdk/node\n```\n\n### 2. Set your API key\n\n```bash\n# Secret key - full API access (server-side only, never expose publicly)\nexport DRIP_API_KEY=sk_test_...\n\n# Use a secret key for the customer, billing, runs, pricing-plan, and webhook\n# flows documented in this reference.\n```\n\nOr use a \".env\" file (recommended):\n\n```bash\nnpm install dotenv\n# .env\nDRIP_API_KEY=sk_test_...\n```\n\nLoad your \".env\" at the top of your entry file:\n\n```typescript\nimport 'dotenv/config';\n```\n\n### 3. Create a customer and track usage\n\n```typescript\nimport 'dotenv/config';\nimport { drip } from '@drip-sdk/node';\n\n// Create a customer first\nconst customer = await drip.createCustomer({ externalCustomerId: 'user_123' });\n\n// Internal tracking only (no billing)\nawait drip.trackUsage({ customerId: customer.id, meter: 'api_calls', quantity: 1 });\n```\n\nThe `drip` singleton reads `DRIP_API_KEY` from your environment automatically.\n\n### Alternative: Explicit Configuration\n\n```typescript\nimport 'dotenv/config';\nimport { Drip } from '@drip-sdk/node';\n\n// Auto-reads DRIP_API_KEY from environment\nconst client = new Drip();\n\n// Or pass config explicitly with an Admin/Operator secret key\nconst clientWithSecret = new Drip({ apiKey: 'sk_test_...' });\n```\n\n### Full Example (Node.js)\n\n```typescript\nimport 'dotenv/config';\nimport { drip } from '@drip-sdk/node';\n\nasync function main() {\n  // Verify connectivity\n  await drip.ping();\n\n  // Create a customer (at least one of externalCustomerId or onchainAddress required)\n  const customer = await drip.createCustomer({ externalCustomerId: 'user_123' });\n\n  // Internal tracking (no billing)\n  await drip.trackUsage({\n    customerId: customer.id,\n    meter: 'llm_tokens',\n    quantity: 842,\n    metadata: { model: 'gpt-4o-mini' },\n  });\n\n  // Billable usage\n  await drip.charge({\n    customerId: customer.id,\n    meter: 'api_calls',\n    quantity: 1,\n  });\n\n  // Record an execution lifecycle\n  await drip.recordRun({\n    customerId: customer.id,\n    workflow: 'research-agent',\n    events: [\n      { eventType: 'llm.call', quantity: 1700, units: 'tokens' },\n      { eventType: 'tool.call', quantity: 1 },\n    ],\n    status: 'COMPLETED',\n  });\n\n  console.log(`Customer ${customer.id}: usage + run recorded`);\n}\n\nmain();\n```\n\n```python\nfrom drip import drip\n\n# Create a customer first\ncustomer = drip.create_customer(external_customer_id=\"user_123\")\n\n# Internal tracking only (no billing)\ndrip.track_usage(customer_id=customer.id, meter=\"api_calls\", quantity=1)\n```\n\nThe `drip` singleton reads `DRIP_API_KEY` from your environment automatically.\n\n### Alternative: Explicit Configuration (Python)\n\n```python\nfrom drip import Drip\n\n# Auto-reads DRIP_API_KEY from environment\nclient = Drip()\n\n# Or pass config explicitly with an Admin/Operator secret key\nclient_with_secret = Drip(api_key=\"sk_test_...\")\n```\n\n### Full Example (Python)\n\n```python\nfrom drip import drip\n\n# Verify connectivity\ndrip.ping()\n\n# Create a customer (at least one of external_customer_id or onchain_address required)\ncustomer = drip.create_customer(external_customer_id=\"user_123\")\n\n# Internal tracking (no billing)\ndrip.track_usage(\n    customer_id=customer.id,\n    meter=\"llm_tokens\",\n    quantity=842,\n    metadata={\"model\": \"gpt-4o-mini\"}\n)\n\n# Billable usage\ndrip.charge(\n    customer_id=customer.id,\n    meter=\"api_calls\",\n    quantity=1\n)\n\n# Record execution lifecycle\ndrip.record_run(\n    customer_id=customer.id,\n    workflow=\"research-agent\",\n    events=[\n        {\"event_type\": \"llm.call\", \"quantity\": 1700, \"units\": \"tokens\"},\n        {\"event_type\": \"tool.call\", \"quantity\": 1},\n    ],\n    status=\"COMPLETED\"\n)\n\nprint(f\"Customer {customer.id}: usage + run recorded\")\n```\n\n**Expected result:**\n- No errors\n- Events appear in your Drip dashboard within seconds\n\n**Install:** `npm install @drip-sdk/node` or `pip install drip-sdk`\n\n**Set API key:** `export DRIP_API_KEY=sk_test_...` or use a \".env\" file with `DRIP_API_KEY=sk_test_...` and load it with `import 'dotenv/config'` (for Node.js)\n\n---\n\n## REST API Quick Start\n\n### Step 1: Create a customer\n\n```bash\ncurl -X POST https://api.drippay.dev/v1/customers \\\n  -H \"Authorization: Bearer sk_test_YOUR_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"externalCustomerId\": \"user_123\"}'\n```\n\n**You'll get back:**\n```json\n{\n  \"id\": \"cmlxxxxxx...\",\n  \"externalCustomerId\": \"user_123\",\n  \"status\": \"ACTIVE\"\n}\n```\n\n### Step 2: Create pricing\n\nUse the same meter string in your pricing plan and your usage calls:\n\n```bash\ncurl -X POST https://api.drippay.dev/v1/pricing-plans \\\n  -H \"Authorization: Bearer sk_test_YOUR_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"API Calls\",\n    \"unitType\": \"api_calls\",\n    \"unitPriceUsd\": 0.001\n  }'\n```\n\n### Step 3: Charge usage\n\n```bash\ncurl -X POST https://api.drippay.dev/v1/usage \\\n  -H \"Authorization: Bearer sk_test_YOUR_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"customerId\": \"CUSTOMER_ID_FROM_STEP_1\",\n    \"usageType\": \"api_calls\",\n    \"quantity\": 100,\n    \"idempotencyKey\": \"charge_001\"\n  }'\n```\n\n---\n\n## SDK Methods\n\n### Node.js (`@drip-sdk/node`)\n\n| Method | Description |\n|--------|-------------|\n| `createCustomer()` | Create a customer |\n| `getCustomer()` | Get customer details |\n| `listCustomers()` | List all customers |\n| `trackUsage()` | Record internal usage without billing |\n| `charge()` | Record usage and charge (requires pricing plan) |\n| `emitEvent()` | Record an execution event |\n| `recordRun()` | Record a complete agent run |\n| `startRun()` | Start a run |\n| `endRun()` | End a run |\n| `getBalance()` | Get customer balance |\n\n### Python (`drip-sdk`)\n\n| Method | Description |\n|--------|-------------|\n| `create_customer()` | Create a customer |\n| `get_customer()` | Get customer details |\n| `list_customers()` | List all customers |\n| `track_usage()` | Record internal usage without billing |\n| `charge()` | Record usage and charge (requires pricing plan) |\n| `emit_event()` | Record an execution event |\n| `record_run()` | Record a complete agent run |\n| `start_run()` | Start a run |\n| `end_run()` | End a run |\n| `get_balance()` | Get customer balance |\n\n---\n\n## Two Modes\n\n| Mode | How | When |\n|------|-----|------|\n| **Tracking only** | `trackUsage()` / `track_usage()` | Pilots, analytics, no billing yet |\n| **Billing** | `charge()` + pricing plan | Ready to charge customers |\n\nBoth modes record usage in the ledger. The difference is whether a charge is created.\n\nUse `POST /v1/usage/internal` when you want tracking only.\n\n---\n\n## Authentication\n\n```\nAuthorization: Bearer sk_test_YOUR_KEY\n```\n\n### Key Types\n\n| Key Prefix | Use For |\n|------------|---------|\n| `sk_test_*` / `sk_live_*` | Server-side API access (secret key) |\n| `pk_test_*` / `pk_live_*` | Public key identifier. The role-protected endpoints in this reference require a secret key |\n\n### API Key Roles\n\nSecret keys (`sk_*`) are assigned a role that controls which endpoints they can access. Roles are hierarchical: higher roles include all permissions of lower roles.\n\n| Role | Level | Permissions |\n|------|-------|-------------|\n| `READONLY` | Lowest | List and read resources (customers, charges, pricing plans, events) |\n| `OPERATOR` | Mid | + Create customers, charge usage, track internal usage, emit events, manage runs |\n| `ADMIN` | Highest | + Create/update/delete pricing plans, manage contracts, manage API keys |\n\nPublic keys (`pk_*`) are always `READONLY`: they cannot create or modify resources.\n\n> **Important:** To create, update, or delete **pricing plans** and **contracts**, you must use a secret key (`sk_*`) with the **ADMIN** role. Using a lower-role key returns `403 Forbidden`.\n\n---\n\n## Idempotency\n\nAlways include `idempotencyKey` in POST requests to prevent duplicates:\n\n```json\n{\n  \"customerId\": \"cmlxxxxxx...\",\n  \"usageType\": \"api_calls\",\n  \"quantity\": 1,\n  \"idempotencyKey\": \"req_unique_12345\"\n}\n```\n\nSame key = same result. Safe to retry on network failures.\n\n---\n\n## Error Codes\n\n| Status | Meaning | Fix |\n|--------|---------|-----|\n| **400** | Bad request | Check request body matches schema |\n| **401** | Invalid API key | Verify `Authorization: Bearer sk_...` header |\n| **404** | Not found | Customer/pricing plan doesn't exist. Create customer first. |\n| **409** | Duplicate | Resource with this ID already exists |\n| **422** | Validation error | Check required fields and types |\n\n---\n\n## Important Notes\n\n- **Always create a customer first** for billable onboarding flows. You cannot use made-up customer IDs.\n- **`POST /v1/events`** records execution events (what happened). It does **not** auto-create charges.\n- **`POST /v1/usage`** records usage and creates charges if a matching pricing plan exists.\n- **`POST /v1/usage/internal`** records usage without billing.\n- **Numbers as strings**: Monetary amounts are returned as strings (e.g., `\"0.001000\"`) to preserve precision.\n"
  version: 1.0.0
  contact:
    name: Drip Support
    email: support@drippay.dev
  x-logo:
    url: https://drippay.dev/logo.svg
    altText: Drip
servers:
- url: https://api.drippay.dev
  description: Production
- url: http://localhost:3001
  description: Development
security:
- bearerAuth: []
tags:
- name: Workflows
  description: Define workflow templates for agent execution.
paths:
  /v1/workflows:
    post:
      operationId: createWorkflow
      summary: Create a workflow
      tags:
      - Workflows
      description: Create a new workflow definition for tracking agent runs.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Request body for creating a new workflow.
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 255
                  description: Human-readable name for the workflow (required)
                slug:
                  type: string
                  minLength: 1
                  maxLength: 100
                  pattern: ^[a-z0-9_-]+$
                  description: URL-safe identifier - must be lowercase alphanumeric with underscores or hyphens (required)
                productSurface:
                  type: string
                  enum:
                  - API
                  - RPC
                  - WEBHOOK
                  - AGENT
                  - PIPELINE
                  - CUSTOM
                  description: Product category for dashboard grouping. Use API for REST APIs, RPC for blockchain calls, WEBHOOK for webhooks, AGENT for AI agents, PIPELINE for data pipelines, CUSTOM for other use cases.
                  default: CUSTOM
                chain:
                  type: string
                  enum:
                  - ETHEREUM
                  - SOLANA
                  - POLYGON
                  - ARBITRUM
                  - OPTIMISM
                  - BASE
                  - AVALANCHE
                  - BSC
                  description: Blockchain network (optional, for RPC workflows only)
                description:
                  type: string
                  maxLength: 1000
                  description: Optional description of what this workflow does
                metadata:
                  type: object
                  additionalProperties: true
                  description: Optional metadata for custom tracking
              required:
              - name
              - slug
        description: Request body for creating a new workflow.
      responses:
        '201':
          description: Workflow created
          content:
            application/json:
              schema:
                description: Workflow created
                type: object
                properties:
                  id:
                    type: string
                    description: Unique identifier for the workflow
                  name:
                    type: string
                    description: Human-readable name for the workflow
                  slug:
                    type: string
                    description: URL-safe identifier (lowercase, alphanumeric, hyphens, underscores)
                  productSurface:
                    type: string
                    enum:
                    - API
                    - RPC
                    - WEBHOOK
                    - AGENT
                    - PIPELINE
                    - CUSTOM
                    description: Product category for dashboard grouping. API = REST API calls, RPC = Blockchain RPC calls, WEBHOOK = Webhook deliveries, AGENT = AI agent executions, PIPELINE = Data pipelines, CUSTOM = Custom workflows
                  chain:
                    type: string
                    enum:
                    - ETHEREUM
                    - SOLANA
                    - POLYGON
                    - ARBITRUM
                    - OPTIMISM
                    - BASE
                    - AVALANCHE
                    - BSC
                    nullable: true
                    description: Blockchain network for RPC workflows (optional)
                  description:
                    type: string
                    nullable: true
                    description: Optional description of what this workflow does
                  metadata:
                    type: object
                    additionalProperties: true
                    nullable: true
                    description: Optional metadata for custom tracking
                  isActive:
                    type: boolean
                    description: Whether this workflow is currently active
                  createdAt:
                    type: string
                    format: date-time
                    description: When the workflow was created
                  updatedAt:
                    type: string
                    format: date-time
                    description: When the workflow was last updated
                required:
                - id
                - name
                - slug
                - productSurface
                - isActive
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                description: Validation error
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  code:
                    type: string
                    description: Error code
                  details:
                    type: array
                    items:
                      type: object
                      properties:
                        path:
                          type: string
                        message:
                          type: string
                    description: Validation error details
                required:
                - error
                - code
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                description: Unauthorized
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  code:
                    type: string
                    description: Error code
                  details:
                    type: array
                    items:
                      type: object
                      properties:
                        path:
                          type: string
                        message:
                          type: string
                    description: Validation error details
                required:
                - error
                - code
        '409':
          description: Workflow with this slug already exists
          content:
            application/json:
              schema:
                description: Workflow with this slug already exists
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  code:
                    type: string
                    description: Error code
                  details:
                    type: array
                    items:
                      type: object
                      properties:
                        path:
                          type: string
                        message:
                          type: string
                    description: Validation error details
                required:
                - error
                - code
    get:
      operationId: listWorkflows
      summary: List workflows
      tags:
      - Workflows
      description: List all workflows for your business.
      parameters:
      - schema:
          type: string
          enum:
          - API
          - RPC
          - WEBHOOK
          - AGENT
          - PIPELINE
          - CUSTOM
        in: query
        name: productSurface
        required: false
      - schema:
          type: boolean
        in: query
        name: isActive
        required: false
      - schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 50
        in: query
        name: limit
        required: false
      responses:
        '200':
          description: List of workflows
          content:
            application/json:
              schema:
                description: List of workflows
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        name:
                          type: string
                        slug:
                          type: string
                        productSurface:
                          type: string
                        description:
                          type: string
                          nullable: true
                        isActive:
                          type: boolean
                        runCount:
                          type: integer
                        createdAt:
                          type: string
                          format: date-time
                  count:
                    type: integer
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                description: Unauthorized
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  code:
                    type: string
                    description: Error code
                  details:
                    type: array
                    items:
                      type: object
                      properties:
                        path:
                          type: string
                        message:
                          type: string
                    description: Validation error details
                required:
                - error
                - code
  /v1/workflows/{id}:
    get:
      operationId: getWorkflow
      summary: Get workflow
      tags:
      - Workflows
      description: Get a workflow by ID with usage statistics.
      parameters:
      - schema:
          type: string
        in: path
        name: id
        required: true
      responses:
        '200':
          description: Workflow details
          content:
            application/json:
              schema:
                description: Workflow details
                type: object
                properties:
                  id:
                    type: string
                  name:
                    type: string
                  slug:
                    type: string
                  productSurface:
                    type: string
                  description:
                    type: string
                    nullable: true
                  metadata:
                    type: object
                    nullable: true
                  isActive:
                    type: boolean
                  stats:
                    type: object
                    properties:
                      totalRuns:
                        type: integer
                      completedRuns:
                        type: integer
                      failedRuns:
                        type: integer
                      totalEvents:
                        type: integer
                      totalCostUnits:
                        type: string
                  createdAt:
                    type: string
                    format: date-time
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                description: Unauthorized
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  code:
                    type: string
                    description: Error code
                  details:
                    type: array
                    items:
                      type: object
                      properties:
                        path:
                          type: string
                        message:
                          type: string
                    description: Validation error details
                required:
                - error
                - code
        '404':
          description: Workflow not found
          content:
            application/json:
              schema:
                description: Workflow not found
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  code:
                    type: string
                    description: Error code
                  details:
                    type: array
                    items:
                      type: object
                      properties:
                        path:
                          type: string
                        message:
                          type: string
                    description: Validation error details
                required:
                - error
                - code
    patch:
      operationId: updateWorkflow
      summary: Update workflow
      tags:
      - Workflows
      parameters:
      - schema:
          type: string
        in: path
        name: id
        required: true
      responses:
        '200':
          description: Workflow updated
          content:
            application/json:
              schema:
                description: Workflow updated
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                description: Unauthorized
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  code:
                    type: string
                    description: Error code
                  details:
                    type: array
                    items:
                      type: object
                      properties:
                        path:
                          type: string
                        message:
                          type: string
                    description: Validation error details
                required:
                - error
                - code
        '404':
          description: Workflow not found
          content:
            application/json:
              schema:
                description: Workflow not found
                type: object
                properties:
                  error:
                    type: string
                    description: Error message
                  code:
                    type: string
                    description: Error code
                  details:
                    type: array
                    items:
                      type: object
                      properties:
                        path:
                          type: string
                        message:
                          type: string
                    description: Validation error details
                required:
                - error
                - code
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: 'API key from Drip Dashboard. Format: `sk_live_...` or `sk_test_...`'