{
  "openapi": "3.1.0",
  "info": {
    "title": "iris API",
    "version": "2.3.0",
    "description": "iris — the ai messenger. manage campaigns, contacts, conversations, content generation, analytics, and more.",
    "contact": {
      "name": "iris",
      "url": "https://www.iris-ai.dev"
    },
    "x-guidance": "iris runs multi-channel AI outreach campaigns (email, Twitter DM, Instagram DM). most endpoints require an API key (Authorization: Bearer is_live_...) - create one at https://www.iris-ai.dev/settings/api. POST /campaigns is the only paid operation: x402 wallets pay $2.25 USDC on Base per campaign; MPP agents buy a 5-credit pack for $12.00 at POST /agent/credits ($2.40 effective per campaign). 1 credit covers contact discovery, AI drafting, and 240 message sends. iris does not offer an x402 free tier. see https://www.iris-ai.dev/docs#agent-payments for the full payment flow and https://api.iris-ai.dev/llms.txt for product context."
  },
  "x-discovery": {
    "ownershipProofs": [
      "domain:api.iris-ai.dev",
      "wellknown:https://api.iris-ai.dev/.well-known/x402"
    ]
  },
  "x-service-info": {
    "categories": [
      "outreach",
      "marketing",
      "messaging",
      "automation"
    ],
    "docs": {
      "homepage": "https://www.iris-ai.dev",
      "apiReference": "https://www.iris-ai.dev/docs",
      "llms": "https://api.iris-ai.dev/llms.txt"
    }
  },
  "servers": [
    {
      "url": "https://api.iris-ai.dev",
      "description": "production"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "tags": [
    {
      "name": "authentication",
      "description": "verify your API key and view its metadata."
    },
    {
      "name": "API keys",
      "description": "programmatically manage API keys. all routes in this group (except `/keys/me`) require an API key with the `admin` scope. `/keys/me` returns metadata for the currently-authenticated key and works without any scope."
    },
    {
      "name": "campaigns",
      "description": "create and manage outreach campaigns."
    },
    {
      "name": "contacts",
      "description": "manage contacts and import leads."
    },
    {
      "name": "conversations",
      "description": "manage conversations across all channels."
    },
    {
      "name": "messages",
      "description": "manage message approval workflow and sending."
    },
    {
      "name": "AI",
      "description": "AI-powered content generation and analysis."
    },
    {
      "name": "discovery",
      "description": "search for and discover new contacts."
    },
    {
      "name": "analytics",
      "description": "campaign performance metrics and reporting."
    },
    {
      "name": "billing",
      "description": "view billing plans and subscription information."
    },
    {
      "name": "channels",
      "description": "manage connected accounts and multi-channel messaging."
    },
    {
      "name": "notifications",
      "description": "manage user notifications."
    },
    {
      "name": "webhooks",
      "description": "manage webhook endpoints for receiving real-time event notifications. all routes in this group require an API key with the `admin` scope (round-6 audit closed a privilege-escalation gap where a non-admin key could create or rotate webhooks)."
    },
    {
      "name": "agent credits",
      "description": "credit-based payments for AI agents using x402 (USDC on Base) or MPP (Stripe). 1 credit = 1 campaign (30 contacts, 240 messages, AI drafting bundled in). no subscription required."
    }
  ],
  "paths": {
    "/keys/me": {
      "get": {
        "tags": [
          "authentication"
        ],
        "summary": "get information about the currently authenticated API key",
        "operationId": "getCurrentKey",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/ApiKey"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "uuid",
                    "name": "production",
                    "key_prefix": "is_live_a1b2c3d4",
                    "scopes": [
                      "*"
                    ],
                    "last_used_at": "2024-01-15T10:30:00Z",
                    "is_active": true
                  }
                }
              }
            }
          }
        }
      }
    },
    "/keys": {
      "get": {
        "tags": [
          "API keys"
        ],
        "summary": "list all API keys for your account",
        "operationId": "listKeys",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ApiKey"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "uuid",
                      "name": "production",
                      "key_prefix": "is_live_a1b2c3d4",
                      "scopes": [
                        "*"
                      ],
                      "is_active": true,
                      "last_used_at": "2024-01-15T10:30:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "page_size": 50,
                    "total": 1,
                    "total_pages": 1
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "page number",
            "schema": {
              "type": "integer",
              "default": "1"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "items per page",
            "schema": {
              "type": "integer",
              "default": "50"
            }
          }
        ]
      },
      "post": {
        "tags": [
          "API keys"
        ],
        "summary": "create a new API key. the raw key is only returned once.",
        "operationId": "createKey",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/CreateApiKeyResponse"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "uuid",
                    "name": "staging",
                    "key_prefix": "is_live_e5f6g7h8",
                    "key": "is_live_e5f6g7h8a9b0c1d2e3f4g5h6i7j8k9l0m1n2o3p4",
                    "scopes": [
                      "read"
                    ],
                    "is_active": true
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "key name (1-100 characters)"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "permission scopes (any of: read, write, delete, generate, send, admin). defaults to [\"*\"] for full access"
                  },
                  "expires_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "optional expiration date"
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "description": "the raw key value is only returned on creation - store it securely"
      }
    },
    "/keys/{id}": {
      "patch": {
        "tags": [
          "API keys"
        ],
        "summary": "rename an API key. only the display label is updated; the secret, scopes, and expiry are untouched.",
        "operationId": "updateKey",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/ApiKey"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "uuid",
                    "name": "renamed key",
                    "key_prefix": "is_live_abcd",
                    "scopes": [
                      "read",
                      "write"
                    ],
                    "last_used_at": "2026-04-29T12:00:00Z",
                    "expires_at": null,
                    "revoked_at": null,
                    "created_at": "2026-04-01T12:00:00Z",
                    "updated_at": "2026-04-29T13:00:00Z"
                  }
                }
              }
            }
          },
          "404": {
            "description": "APIKEY_006: API key not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "new display name (1-100 chars)"
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "API keys"
        ],
        "summary": "revoke an API key. this action is irreversible.",
        "operationId": "deleteKey",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResult"
                },
                "example": {
                  "success": true,
                  "data": null
                }
              }
            }
          },
          "404": {
            "description": "APIKEY_006: API key not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/keys/{id}/rotate": {
      "post": {
        "tags": [
          "API keys"
        ],
        "summary": "rotate an API key — revokes the old key and creates a new one with the same name and scopes. the new raw key is returned exactly once. update stored credentials immediately — the old key stops authenticating as soon as this returns. cannot rotate the key being used for the request itself (would lock the caller out mid-rotation).",
        "operationId": "createRotate",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/CreateApiKeyResponse"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "uuid",
                    "name": "my integration",
                    "key_prefix": "is_live_xyz...",
                    "scopes": [
                      "read",
                      "write",
                      "generate",
                      "send"
                    ],
                    "last_used_at": null,
                    "expires_at": null,
                    "revoked_at": null,
                    "created_at": "2026-05-07T12:00:00Z",
                    "updated_at": "2026-05-07T12:00:00Z",
                    "key": "is_live_xyz...thefullnewkeyshownonceonly"
                  }
                }
              }
            }
          },
          "404": {
            "description": "APIKEY_006: API key not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "SERVER_005: cannot rotate the API key currently being used",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ],
        "description": "the new key's `id` is different from the old `id` — update any stored references.\n\nthe underlying service makes the usage counter net-zero, so rotation never trips MAX_ACTIVE_KEYS_PER_USER even when the user is at the limit."
      }
    },
    "/campaigns": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "list all campaigns",
        "operationId": "listCampaigns",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Campaign"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "uuid",
                      "name": "Q1 outreach",
                      "objective_type": "product_promotion",
                      "status": "active",
                      "total_contacts": 150,
                      "contacts_reached": 42,
                      "responses_received": 8,
                      "created_at": "2024-01-15T10:30:00Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "page_size": 50,
                    "total": 1,
                    "total_pages": 1
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "page number",
            "schema": {
              "type": "integer",
              "default": "1"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "items per page",
            "schema": {
              "type": "integer",
              "default": "50"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "filter by status (draft, active, paused, completed)",
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "create a new campaign",
        "operationId": "createCampaign",
        "security": [
          {
            "apiKey": []
          },
          {
            "agentPaymentAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Campaign"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "uuid",
                    "name": "spring outreach",
                    "objective_type": "product_promotion",
                    "status": "draft",
                    "created_at": "2024-01-15T10:30:00Z"
                  }
                }
              }
            }
          },
          "402": {
            "description": "payment required — agent payment auth (x402 or MPP). campaign creation costs $2.25 via x402 (crypto) or 1 credit ($2.40 effective via MPP credit pack).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "PAYMENT_005"
                        },
                        "message": {
                          "type": "string",
                          "example": "insufficient credits — pay $2.25 USDC per campaign (x402) or buy a 5-credit pack for $12.00 (MPP)"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    },
                    "x402": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "integer",
                          "example": 2
                        },
                        "scheme": {
                          "type": "string",
                          "example": "exact"
                        },
                        "network": {
                          "type": "string",
                          "example": "eip155:8453"
                        },
                        "asset": {
                          "type": "string",
                          "example": "USDC"
                        },
                        "amount": {
                          "type": "string",
                          "example": "2.25"
                        },
                        "receiver": {
                          "type": "string"
                        },
                        "resource": {
                          "type": "string"
                        }
                      }
                    },
                    "mpp": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "integer",
                          "example": 1
                        },
                        "method": {
                          "type": "string",
                          "example": "stripe"
                        },
                        "intent": {
                          "type": "string",
                          "example": "charge"
                        },
                        "currency": {
                          "type": "string",
                          "example": "usd"
                        },
                        "amount_cents": {
                          "type": "integer",
                          "example": 1200
                        },
                        "resource": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "CAMP_009: campaign limit reached for billing period",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "campaign name"
                  },
                  "objective_type": {
                    "type": "string",
                    "description": "free-text 2-5 word goal summary (e.g. 'venue_host', 'promote my coffee shop'). apify scraper routing uses target_profile_type, not this field."
                  },
                  "product_name": {
                    "type": "string",
                    "description": "product name (for product_promotion objective)"
                  },
                  "product_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "product URL for AI analysis"
                  },
                  "product_description": {
                    "type": "string",
                    "description": "product description for AI context"
                  }
                },
                "required": [
                  "name",
                  "objective_type"
                ]
              }
            }
          }
        },
        "description": "agent payments: this is the only paid operation in the public API for agents. x402 agents pay $2.25 USDC per campaign — read the PAYMENT-REQUIRED header from the 402, sign it, and replay with a PAYMENT-SIGNATURE header (x402 v2). MPP agents deduct 1 credit from a credit pack ($2.40 effective). discovery, AI drafting, and message sends run automatically inside the campaign workflow as internal QStash jobs — agents never call /discovery/search, /ai/generate, or /channels/send directly (those endpoints require an API key).\n\niris does not offer an x402 free tier - every agent campaign requires payment.\n\nsee the agent-payments and credit-packs sections for the full 402 challenge flow.",
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "2.250000"
          },
          "protocols": [
            {
              "x402": {}
            },
            {
              "mpp": {
                "method": "stripe",
                "intent": "charge",
                "currency": "usd"
              }
            }
          ]
        }
      }
    },
    "/campaigns/{id}": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "get a specific campaign with full details",
        "operationId": "getCampaign",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Campaign"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      },
      "patch": {
        "tags": [
          "campaigns"
        ],
        "summary": "update a campaign",
        "operationId": "updateCampaign",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Campaign"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "CAMP_008: invalid status transition",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "campaign name"
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "draft",
                      "active",
                      "paused",
                      "completed"
                    ],
                    "description": "campaign status"
                  },
                  "product_name": {
                    "type": "string",
                    "description": "product name"
                  },
                  "product_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "product URL"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "campaigns"
        ],
        "summary": "soft-delete a campaign (sets status to 'deleted')",
        "operationId": "deleteCampaign",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResult"
                },
                "example": {
                  "success": true,
                  "data": null
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/campaigns/{id}/contacts": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "list contacts in a campaign",
        "operationId": "listCampaignContacts",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CampaignContact"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "page number",
            "schema": {
              "type": "integer",
              "default": "1"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "items per page",
            "schema": {
              "type": "integer",
              "default": "50"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "filter by contact status",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/campaigns/{id}/usage": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "get campaign usage statistics",
        "operationId": "getCampaignUsage",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/CampaignUsage"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "total_contacts": 150,
                    "contacts_reached": 42,
                    "responses_received": 8,
                    "emails_sent": 42,
                    "emails_opened": 28,
                    "emails_clicked": 12
                  }
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/campaigns/{id}/analyze": {
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "trigger AI product analysis for a campaign",
        "operationId": "analyzeCampaign",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Campaign"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "AI_004: AI rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ],
        "description": "analyzes the campaign's product URL/description and generates target profiles\n\nreturns immediately - analysis runs asynchronously"
      }
    },
    "/campaigns/{id}/target-profiles": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "list target profiles for a campaign",
        "operationId": "listTargetProfiles",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TargetProfile"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "uuid",
                      "campaign_id": "uuid",
                      "name": "SaaS founders",
                      "profile_type": "b2b_professional",
                      "fit_score": 85,
                      "job_titles": [
                        "CEO",
                        "CTO",
                        "founder"
                      ],
                      "industries": [
                        "technology",
                        "SaaS"
                      ],
                      "discovery_keywords": [
                        "saas founder",
                        "tech startup"
                      ],
                      "recommended_channels": [
                        "email",
                        "twitter"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      },
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "create a target profile for a campaign",
        "operationId": "createTargetProfile",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/TargetProfile"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "profile name"
                  },
                  "profile_type": {
                    "type": "string",
                    "enum": [
                      "local_business",
                      "content_creator",
                      "influencer",
                      "b2b_professional",
                      "ecommerce",
                      "saas_company",
                      "agency",
                      "freelancer",
                      "other"
                    ],
                    "description": "target profile type"
                  },
                  "job_titles": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "target job titles"
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "target industries"
                  },
                  "discovery_keywords": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "keywords for contact discovery"
                  },
                  "recommended_channels": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "recommended outreach channels"
                  }
                },
                "required": [
                  "name",
                  "profile_type"
                ]
              }
            }
          }
        }
      }
    },
    "/campaigns/{id}/target-profiles/{profileId}": {
      "delete": {
        "tags": [
          "campaigns"
        ],
        "summary": "delete a target profile",
        "operationId": "deleteTargetProfile",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResult"
                },
                "example": {
                  "success": true,
                  "data": null
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign or profile not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          },
          {
            "name": "profileId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "profileId"
          }
        ]
      }
    },
    "/contacts": {
      "get": {
        "tags": [
          "contacts"
        ],
        "summary": "list all contacts",
        "operationId": "listContacts",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Contact"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "uuid",
                      "email": "jane@example.com",
                      "first_name": "Jane",
                      "last_name": "Smith",
                      "company_name": "Acme Inc",
                      "tags": [
                        "lead",
                        "enterprise"
                      ]
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "page_size": 50,
                    "total": 1,
                    "total_pages": 1
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "page number",
            "schema": {
              "type": "integer",
              "default": "1"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "items per page",
            "schema": {
              "type": "integer",
              "default": "50"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "search by name or email",
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "tags": [
          "contacts"
        ],
        "summary": "create a single contact. idempotent on email — if a contact with the same email already exists for this user, returns 201 with the existing record (merging any new fields you supply) instead of 409.",
        "operationId": "createContact",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Contact"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "CONTACT_009: contact limit reached for billing period",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "contact email"
                  },
                  "first_name": {
                    "type": "string",
                    "description": "first name"
                  },
                  "last_name": {
                    "type": "string",
                    "description": "last name"
                  },
                  "company_name": {
                    "type": "string",
                    "description": "company name"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "tags for categorization"
                  },
                  "campaign_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "campaign to associate with"
                  }
                },
                "required": [
                  "email"
                ]
              }
            }
          }
        }
      }
    },
    "/contacts/{id}": {
      "get": {
        "tags": [
          "contacts"
        ],
        "summary": "get a specific contact",
        "operationId": "getContact",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Contact"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CONTACT_001: contact not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      },
      "patch": {
        "tags": [
          "contacts"
        ],
        "summary": "update a contact",
        "operationId": "updateContact",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Contact"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CONTACT_001: contact not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "first_name": {
                    "type": "string",
                    "description": "first name"
                  },
                  "last_name": {
                    "type": "string",
                    "description": "last name"
                  },
                  "company_name": {
                    "type": "string",
                    "description": "company name"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "tags"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "contacts"
        ],
        "summary": "soft-delete a contact (sets deleted_at timestamp)",
        "operationId": "deleteContact",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResult"
                },
                "example": {
                  "success": true,
                  "data": null
                }
              }
            }
          },
          "404": {
            "description": "CONTACT_001: contact not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/contacts/bulk": {
      "post": {
        "tags": [
          "contacts"
        ],
        "summary": "bulk import contacts (up to 500 per request)",
        "operationId": "bulkCreateContacts",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/BulkContactImportResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "imported": 48,
                    "skipped": 2,
                    "errors": []
                  }
                }
              }
            }
          },
          "429": {
            "description": "CONTACT_009: contact limit reached for billing period",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contacts": {
                    "type": "array",
                    "description": "array of contact objects (email required, first_name/last_name/company_name optional)"
                  },
                  "campaign_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "campaign to associate contacts with"
                  }
                },
                "required": [
                  "contacts"
                ]
              }
            }
          }
        },
        "description": "duplicates are skipped by email. max 500 contacts per request."
      },
      "delete": {
        "tags": [
          "contacts"
        ],
        "summary": "bulk soft-delete contacts by ID",
        "operationId": "bulkDeleteContacts",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/BulkContactDeleteResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "deletedCount": 12
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contact_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "non-empty array of contact IDs to delete"
                  }
                },
                "required": [
                  "contact_ids"
                ]
              }
            }
          }
        },
        "description": "sets deleted_at on each contact - same soft-delete semantics as DELETE /contacts/:id."
      }
    },
    "/contacts/usage": {
      "get": {
        "tags": [
          "contacts"
        ],
        "summary": "get contact usage for the current billing period",
        "operationId": "getContactUsage",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/ContactUsage"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "total_contacts": 1240,
                    "period_contacts": 150,
                    "period_limit": 30,
                    "period_start": "2024-01-01T00:00:00Z",
                    "period_end": "2024-02-01T00:00:00Z"
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "description": "period_limit is per-campaign, not per-period — null on plans where the per-campaign cap is unlimited (admin/team plans).\n\nperiod_contacts counts contacts created in the current billing period; total_contacts is the lifetime count of non-deleted contacts on the account."
      }
    },
    "/contacts/{id}/conversations": {
      "get": {
        "tags": [
          "contacts"
        ],
        "summary": "get conversations for a specific contact",
        "operationId": "listContactConversations",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Conversation"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CONTACT_001: contact not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/conversations": {
      "get": {
        "tags": [
          "conversations"
        ],
        "summary": "list all conversations",
        "operationId": "listConversations",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Conversation"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "page number",
            "schema": {
              "type": "integer",
              "default": "1"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "items per page",
            "schema": {
              "type": "integer",
              "default": "50"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "filter by status (active, completed, failed, human_review)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "description": "filter by campaign",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/conversations/{id}": {
      "get": {
        "tags": [
          "conversations"
        ],
        "summary": "get a conversation with details",
        "operationId": "getConversation",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/ConversationDetail"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CONVERSATION_001: conversation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/conversations/{id}/messages": {
      "get": {
        "tags": [
          "conversations"
        ],
        "summary": "get messages for a conversation",
        "operationId": "listConversationMessages",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Message"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CONVERSATION_001: conversation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/conversations/{id}/read": {
      "post": {
        "tags": [
          "conversations"
        ],
        "summary": "mark a conversation as read",
        "operationId": "markConversationRead",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/MarkConversationReadResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": null
                }
              }
            }
          },
          "404": {
            "description": "CONVERSATION_001: conversation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/conversations/engagement": {
      "get": {
        "tags": [
          "conversations"
        ],
        "summary": "get engagement metrics across conversations",
        "operationId": "getEngagement",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/EngagementMetrics"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "total_conversations": 250,
                    "active_conversations": 42,
                    "response_rate": 0.28,
                    "avg_response_time_hours": 4.5
                  }
                }
              }
            }
          }
        },
        "x-scope": "read"
      }
    },
    "/messages/pending": {
      "get": {
        "tags": [
          "messages"
        ],
        "summary": "list messages pending approval",
        "operationId": "listPendingMessages",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PendingMessage"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "page number",
            "schema": {
              "type": "integer",
              "default": "1"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "items per page",
            "schema": {
              "type": "integer",
              "default": "50"
            }
          },
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "description": "filter by campaign",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/messages/{id}/approve": {
      "post": {
        "tags": [
          "messages"
        ],
        "summary": "approve a pending message for sending",
        "operationId": "approveMessage",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/ApproveMessageResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "MESSAGE_005: message not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "MESSAGE_004: message already approved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "send",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/messages/{id}/reject": {
      "post": {
        "tags": [
          "messages"
        ],
        "summary": "reject a pending message",
        "operationId": "rejectMessage",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/RejectMessageResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "MESSAGE_005: message not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "send",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "description": "rejection reason"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/messages/{id}/retry": {
      "post": {
        "tags": [
          "messages"
        ],
        "summary": "retry a failed message",
        "operationId": "retryMessage",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/RetryMessageResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "MESSAGE_005: message not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "send",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/messages/{id}/feedback": {
      "post": {
        "tags": [
          "messages"
        ],
        "summary": "submit feedback to revise a message with AI",
        "operationId": "submitMessageFeedback",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/MessageFeedbackResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "MESSAGE_005: message not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "AI_004: AI rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "send",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "feedback": {
                    "type": "string",
                    "description": "revision instructions (e.g. 'make it more casual and shorter')"
                  }
                },
                "required": [
                  "feedback"
                ]
              }
            }
          }
        }
      }
    },
    "/messages/bulk": {
      "post": {
        "tags": [
          "messages"
        ],
        "summary": "bulk approve or reject messages",
        "operationId": "bulkMessageAction",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/BulkMessageActionResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "processed": 5,
                    "failed": 0
                  }
                }
              }
            }
          }
        },
        "x-scope": "send",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "approve",
                      "reject"
                    ],
                    "description": "action to perform"
                  },
                  "message_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "message queue item IDs (1-100)"
                  },
                  "reason": {
                    "type": "string",
                    "description": "rejection reason (only used when action is reject)"
                  }
                },
                "required": [
                  "action",
                  "message_ids"
                ]
              }
            }
          }
        }
      }
    },
    "/ai/generate": {
      "post": {
        "tags": [
          "AI"
        ],
        "summary": "generate AI content (email subject + body)",
        "operationId": "generateAiContent",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/AiGenerateResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "AI_004: AI rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "AI_002: AI generation failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "generate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contact_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "target contact ID"
                  },
                  "conversation_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "conversation ID"
                  },
                  "generation_type": {
                    "type": "string",
                    "enum": [
                      "initial_outreach",
                      "follow_up",
                      "reply"
                    ],
                    "description": "type of content to generate"
                  },
                  "context": {
                    "type": "object",
                    "description": "additional context for generation"
                  }
                },
                "required": [
                  "contact_id",
                  "conversation_id",
                  "generation_type"
                ]
              }
            }
          }
        },
        "description": "requires an API key with `generate` scope. agents do not call this directly — drafting runs as an internal QStash worker inside POST /campaigns."
      }
    },
    "/ai/generate/campaign": {
      "post": {
        "tags": [
          "AI"
        ],
        "summary": "generate campaign-level outreach content (email sequence, templates) from an inline brief. content-first: pass the strategy directly, no campaign id required",
        "operationId": "generateCampaignContent",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/AiGenerateCampaignResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "SERVER_005: missing or invalid request body",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "AI_004: AI rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "generate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "campaign_name": {
                    "type": "string",
                    "description": "campaign name (used as the brief title)"
                  },
                  "objective": {
                    "type": "string",
                    "description": "campaign objective (e.g. \"book DJ gigs\", \"sell SaaS to VPs of Eng\")"
                  },
                  "target_audience": {
                    "type": "string",
                    "description": "target audience description"
                  },
                  "key_benefits": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "non-empty list of key benefits to emphasise"
                  },
                  "tone": {
                    "type": "string",
                    "description": "tone (e.g. professional, casual, warm-direct)"
                  }
                },
                "required": [
                  "campaign_name",
                  "objective",
                  "target_audience",
                  "key_benefits",
                  "tone"
                ]
              }
            }
          }
        }
      }
    },
    "/ai/analyze": {
      "post": {
        "tags": [
          "AI"
        ],
        "summary": "analyze an inbound message (email or DM) for intent, sentiment, key points, and a suggested reply",
        "operationId": "analyzeResponse",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/AiAnalyzeResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "intent_type": "interested",
                    "sentiment": "positive",
                    "key_points": [
                      "asked about pricing for 50 seats",
                      "wants demo next week"
                    ],
                    "suggested_response": "Hi {{first_name}}, ...",
                    "requires_human_review": false,
                    "extracted_data": {
                      "seats": 50,
                      "timing": "next week"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "AI_004: AI rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "generate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "conversation_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "conversation ID — the analysis is scoped to this thread's history and contact"
                  },
                  "message_content": {
                    "type": "string",
                    "description": "inbound message text to analyze. `email_content` is accepted as a legacy alias."
                  }
                },
                "required": [
                  "conversation_id",
                  "message_content"
                ]
              }
            }
          }
        },
        "description": "requires an API key with `generate` scope. agents do not call this directly — response analysis runs as an internal step of the campaign workflow when an inbound reply arrives."
      }
    },
    "/ai/usage": {
      "get": {
        "tags": [
          "AI"
        ],
        "summary": "get AI generation counts for the current billing period, broken down by generation_type. iris does not enforce a separate AI quota - generations are bounded implicitly by the campaign envelope, so no limit field is exposed.",
        "operationId": "getAiUsage",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/AiUsage"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "billing_period_start": "2026-04-30T01:00:04.245Z",
                    "billing_period_end": "2026-05-30T01:00:04.245Z",
                    "total_generations": 14,
                    "total_tokens": 11680,
                    "by_generation_type": {
                      "draft_email": 8,
                      "draft_dm": 4,
                      "suggested_response": 2
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read"
      }
    },
    "/discovery/search": {
      "post": {
        "tags": [
          "discovery"
        ],
        "summary": "run a synchronous contact discovery search across configured sources (Google Maps, social platforms via Apify)",
        "operationId": "searchDiscovery",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/DiscoveryJobHandle"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "contacts": [
                      {
                        "id": "uuid",
                        "name": "Black Cat Cafe",
                        "email": "hello@blackcatcafe.com",
                        "phone": "+1-555-0142",
                        "address": "123 Main St, Brooklyn, NY",
                        "website": "https://blackcatcafe.com",
                        "instagram": "@blackcatcafe",
                        "rating": 4.7,
                        "review_count": 248,
                        "categories": [
                          "cafe",
                          "coffee shop"
                        ],
                        "score": 0.92
                      }
                    ],
                    "total_results": 50,
                    "unique_results": 47,
                    "sources_used": [
                      "google_maps"
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "DISCOVERY_008: discovery quota exceeded; DISCOVERY_006: discovery rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "generate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "keywords": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "non-empty array of keywords to search for (e.g. ['coffee shop', 'cafe'])"
                  },
                  "location": {
                    "type": "string",
                    "description": "location to search around (city, address, lat/lng string)"
                  },
                  "radius_miles": {
                    "type": "string",
                    "description": "search radius in miles",
                    "default": "25"
                  },
                  "max_results": {
                    "type": "integer",
                    "description": "maximum results to return (1-500)",
                    "default": "50"
                  },
                  "sources": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "discovery sources to use (e.g. ['google_maps', 'instagram']). defaults to all available sources"
                  },
                  "campaign_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "campaign to associate discovered contacts with"
                  },
                  "profile_type": {
                    "type": "string",
                    "enum": [
                      "local_business",
                      "content_creator",
                      "influencer",
                      "b2b_professional",
                      "ecommerce",
                      "saas_company",
                      "agency",
                      "freelancer",
                      "other"
                    ],
                    "description": "target profile type, used to route the appropriate Apify scraper"
                  },
                  "enrich_emails": {
                    "type": "boolean",
                    "description": "attempt to enrich discovered contacts with email addresses",
                    "default": "true"
                  }
                },
                "required": [
                  "keywords"
                ]
              }
            }
          }
        },
        "description": "discovery is synchronous - the response includes the contacts directly. there is no job_id to poll.\n\nto fan out a long-running discovery run by target profile, use POST /discovery/search/campaign and poll GET /discovery/jobs/:id.\n\nrequires an API key with `generate` scope. agents do not call this directly — discovery runs as an internal step of POST /campaigns."
      }
    },
    "/discovery/search/campaign": {
      "post": {
        "tags": [
          "discovery"
        ],
        "summary": "run discovery search using campaign target profiles",
        "operationId": "searchCampaignDiscovery",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/DiscoveryJobHandle"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "DISCOVERY_008: discovery quota exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "generate",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "campaign_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "campaign ID"
                  },
                  "target_profile_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "specific target profile to use (defaults to all)"
                  }
                },
                "required": [
                  "campaign_id"
                ]
              }
            }
          }
        }
      }
    },
    "/discovery/jobs/{id}": {
      "get": {
        "tags": [
          "discovery"
        ],
        "summary": "get the status of a discovery job",
        "operationId": "getDiscoveryJob",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/DiscoveryJob"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "uuid",
                    "status": "completed",
                    "contacts_found": 42,
                    "source": "google_maps",
                    "completed_at": "2024-01-15T10:35:00Z"
                  }
                }
              }
            }
          },
          "404": {
            "description": "DISCOVERY_002: discovery job not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/discovery/sources": {
      "get": {
        "tags": [
          "discovery"
        ],
        "summary": "list available discovery data sources",
        "operationId": "listDiscoverySources",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DiscoverySource"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "google_maps",
                      "name": "Google Maps",
                      "available": true
                    },
                    {
                      "id": "instagram",
                      "name": "Instagram",
                      "available": true
                    },
                    {
                      "id": "twitter",
                      "name": "Twitter",
                      "available": true
                    }
                  ]
                }
              }
            }
          }
        },
        "x-scope": "read"
      }
    },
    "/analytics/overview": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "get overall analytics overview across all campaigns",
        "operationId": "getAnalyticsOverview",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/AnalyticsOverview"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "campaigns": {
                      "total": 12,
                      "by_status": {
                        "draft": 4,
                        "active": 3,
                        "completed": 5
                      }
                    },
                    "contacts": {
                      "total": 1250
                    },
                    "conversations": {
                      "total": 450,
                      "by_status": {
                        "active": 120,
                        "closed": 330
                      }
                    },
                    "messages": {
                      "total": 230,
                      "by_status": {
                        "approved": 200,
                        "pending_approval": 30
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "description": "by_status keys are dynamic — they reflect whatever statuses exist in the user's data. Common values: campaigns (draft, active, paused, completed); conversations (active, archived, closed); messages (pending_approval, approved, rejected, sent, failed)."
      }
    },
    "/analytics/campaigns/{id}": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "get analytics for a specific campaign",
        "operationId": "getCampaignAnalytics",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/CampaignAnalytics"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "campaign_id": "uuid",
                    "contacts_total": 150,
                    "contacts_reached": 42,
                    "emails_sent": 42,
                    "emails_opened": 28,
                    "emails_clicked": 12,
                    "responses_received": 8,
                    "response_rate": 0.19,
                    "open_rate": 0.67,
                    "click_rate": 0.29
                  }
                }
              }
            }
          },
          "404": {
            "description": "CAMP_001: campaign not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/analytics/performance": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "get performance metrics over time",
        "operationId": "getPerformanceMetrics",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/PerformanceMetrics"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "time period",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "default": "30d"
            }
          }
        ]
      }
    },
    "/analytics/response-time": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "get average response time metrics",
        "operationId": "getResponseTimeMetrics",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/ResponseTimeMetrics"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "description": "filter by campaign",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/analytics/contact-types": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "get contact type distribution",
        "operationId": "getContactTypeDistribution",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/ContactTypeDistribution"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          }
        },
        "x-scope": "read"
      }
    },
    "/billing/plans": {
      "get": {
        "tags": [
          "billing"
        ],
        "summary": "get available billing plans and their features",
        "operationId": "listPlans",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BillingPlan"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "free",
                      "name": "free",
                      "price_monthly": 0,
                      "limits": {
                        "campaigns": 2,
                        "contacts": 100,
                        "emails_per_month": 50,
                        "ai_generations": 20,
                        "discovery_searches": 5
                      }
                    },
                    {
                      "id": "starter",
                      "name": "starter",
                      "price_monthly": 29,
                      "limits": {
                        "campaigns": 10,
                        "contacts": 1000,
                        "emails_per_month": 500,
                        "ai_generations": 200,
                        "discovery_searches": 25
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "x-scope": "read"
      }
    },
    "/channels/accounts": {
      "get": {
        "tags": [
          "channels"
        ],
        "summary": "list connected social accounts",
        "operationId": "listConnectedAccounts",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ConnectedAccount"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": [
                    {
                      "id": "uuid",
                      "platform": "twitter",
                      "account_name": "@myaccount",
                      "status": "active",
                      "connected_at": "2024-01-15T10:30:00Z"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-scope": "read"
      }
    },
    "/channels/availability": {
      "get": {
        "tags": [
          "channels"
        ],
        "summary": "check which channels are available for messaging",
        "operationId": "getChannelAvailability",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ChannelAvailability"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "email": {
                      "available": true,
                      "configured": true
                    },
                    "twitter": {
                      "available": true,
                      "configured": true
                    },
                    "instagram": {
                      "available": true,
                      "configured": false
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "read"
      }
    },
    "/channels/send": {
      "post": {
        "tags": [
          "channels"
        ],
        "summary": "send a message through a specific channel into an existing conversation",
        "operationId": "sendChannelMessage",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/SendChannelMessageResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "CONVERSATION_001: conversation not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "MESSAGE_015: message limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "send",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "channel": {
                    "type": "string",
                    "enum": [
                      "email",
                      "twitter",
                      "instagram"
                    ],
                    "description": "outreach channel"
                  },
                  "conversation_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "ID of an existing conversation to send the message into"
                  },
                  "recipient_id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "ID of the contact who will receive the message"
                  },
                  "content": {
                    "type": "string",
                    "description": "message content (whitespace is trimmed)"
                  },
                  "subject": {
                    "type": "string",
                    "description": "subject line (email only - ignored for DM channels)"
                  },
                  "variables": {
                    "type": "string",
                    "description": "key/value pairs substituted into the content template (e.g. {{first_name}})"
                  }
                },
                "required": [
                  "channel",
                  "conversation_id",
                  "recipient_id",
                  "content"
                ]
              }
            }
          }
        },
        "description": "prerequisites: the conversation must already exist - there is no API endpoint to create one ad hoc. conversations are created by the campaign-activation flow when contacts are added to an active campaign. for queued AI drafts use the message-approval flow (GET /messages/pending → POST /messages/:id/approve).\n\nprerequisites: twitter and instagram require an OAuth-connected account on the user. connect via the iris dashboard at /settings/channels - there is no API for connecting social accounts.\n\ncheck GET /channels/availability before sending to avoid silent failures on disconnected channels.\n\nrequires an API key with `send` scope. agents do not call this directly — message sends run as an internal step of POST /campaigns + the message approval flow."
      }
    },
    "/notifications": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "list notifications",
        "operationId": "listNotifications",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Notification"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          }
        },
        "x-scope": "read",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "page number",
            "schema": {
              "type": "integer",
              "default": "1"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "items per page",
            "schema": {
              "type": "integer",
              "default": "50"
            }
          }
        ]
      }
    },
    "/notifications/{id}": {
      "patch": {
        "tags": [
          "notifications"
        ],
        "summary": "update a notification (e.g. mark as read)",
        "operationId": "updateNotification",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Notification"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "NOTIFICATION_001: notification not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "read": {
                    "type": "boolean",
                    "description": "mark as read/unread"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "notifications"
        ],
        "summary": "delete a notification",
        "operationId": "deleteNotification",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResult"
                },
                "example": {
                  "success": true,
                  "data": null
                }
              }
            }
          },
          "404": {
            "description": "NOTIFICATION_001: notification not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-scope": "write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/notifications/read-all": {
      "post": {
        "tags": [
          "notifications"
        ],
        "summary": "mark all notifications as read",
        "operationId": "markAllNotificationsRead",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/MarkAllNotificationsReadResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "updated_count": 12
                  }
                }
              }
            }
          }
        },
        "x-scope": "write"
      }
    },
    "/webhooks": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "list all webhook endpoints",
        "operationId": "listWebhooks",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Webhook"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "page number",
            "schema": {
              "type": "integer",
              "default": "1"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "items per page",
            "schema": {
              "type": "integer",
              "default": "50"
            }
          }
        ]
      },
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "create a new webhook endpoint",
        "operationId": "createWebhook",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Webhook"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "uuid",
                    "url": "https://example.com/webhooks/iris",
                    "secret": "whsec_a3f5b9c2d8e1f4a7b6c9d2e5f8a1b4c7d0e3f6a9b2c5d8e1f4a7b0c3d6e9f2a5",
                    "events": [
                      "campaign.created",
                      "contact.created"
                    ],
                    "is_active": true
                  }
                }
              }
            }
          },
          "409": {
            "description": "SERVER_016: a webhook is already registered for this URL. update or delete it before re-creating.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "webhook endpoint URL (HTTPS)"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "event types to subscribe to (e.g. [\"campaign.created\", \"contact.created\"]). use [\"*\"] for all events"
                  },
                  "description": {
                    "type": "string",
                    "description": "optional description"
                  }
                },
                "required": [
                  "url",
                  "events"
                ]
              }
            }
          }
        },
        "description": "the signing secret is only returned on creation - store it securely\n\nnew secrets are prefixed `whsec_`. legacy bare-hex secrets created before the prefix was introduced still verify normally — the HMAC is computed over the stored value as-is.\n\neach (user, url) pair is unique. a 409 means you already have a webhook at that url — PATCH /webhooks/:id to update it, or DELETE /webhooks/:id then re-create."
      }
    },
    "/webhooks/{id}": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "get a specific webhook endpoint",
        "operationId": "getWebhook",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Webhook"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "WEBHOOK_001: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      },
      "patch": {
        "tags": [
          "webhooks"
        ],
        "summary": "update a webhook endpoint",
        "operationId": "updateWebhook",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/Webhook"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "WEBHOOK_001: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "webhook endpoint URL"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "event types"
                  },
                  "is_active": {
                    "type": "boolean",
                    "description": "enable/disable"
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "webhooks"
        ],
        "summary": "delete a webhook endpoint",
        "operationId": "deleteWebhook",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResult"
                },
                "example": {
                  "success": true,
                  "data": null
                }
              }
            }
          },
          "404": {
            "description": "WEBHOOK_001: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/webhooks/{id}/test": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "send a test event to a webhook endpoint",
        "operationId": "testWebhook",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/TestWebhookResponse"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "delivered": true,
                    "response_status": 200,
                    "response_time_ms": 145
                  }
                }
              }
            }
          },
          "404": {
            "description": "WEBHOOK_001: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/webhooks/{id}/deliveries": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "list recent webhook deliveries",
        "operationId": "getWebhookDeliveries",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "page_size": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "total_pages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "page",
                        "page_size",
                        "total",
                        "total_pages"
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "pagination"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "WEBHOOK_001: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "page number",
            "schema": {
              "type": "integer",
              "default": "1"
            }
          },
          {
            "name": "page_size",
            "in": "query",
            "required": false,
            "description": "items per page",
            "schema": {
              "type": "integer",
              "default": "50"
            }
          }
        ]
      }
    },
    "/webhooks/{id}/rotate-secret": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "rotate the signing secret for a webhook. the new secret is returned once and the old secret is invalidated immediately. update HMAC verification on the receiver side before the next delivery, otherwise signature checks will fail.",
        "operationId": "rotateWebhookSecret",
        "security": [
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/RotateSecretResponse"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "id": "uuid",
                    "secret": "whsec_b7c4d1e8f2a5c9d6e3f0a7b4c1d8e5f2a9b6c3d0e7f4a1b8c5d2e9f6a3b0c7d4"
                  }
                }
              }
            }
          },
          "404": {
            "description": "WEBHOOK_001: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "id"
          }
        ]
      }
    },
    "/agent/credits": {
      "get": {
        "tags": [
          "agent credits"
        ],
        "summary": "check the agent's current credit balance",
        "operationId": "listCredits",
        "security": [
          {
            "apiKey": []
          },
          {
            "agentPaymentAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/CreditBalance"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "balance": 7,
                    "identity_id": "uuid"
                  }
                }
              }
            }
          },
          "402": {
            "description": "payment required — agent payment auth (x402 or MPP). campaign creation costs $2.25 via x402 (crypto) or 1 credit ($2.40 effective via MPP credit pack).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "PAYMENT_005"
                        },
                        "message": {
                          "type": "string",
                          "example": "insufficient credits — pay $2.25 USDC per campaign (x402) or buy a 5-credit pack for $12.00 (MPP)"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    },
                    "x402": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "integer",
                          "example": 2
                        },
                        "scheme": {
                          "type": "string",
                          "example": "exact"
                        },
                        "network": {
                          "type": "string",
                          "example": "eip155:8453"
                        },
                        "asset": {
                          "type": "string",
                          "example": "USDC"
                        },
                        "amount": {
                          "type": "string",
                          "example": "2.25"
                        },
                        "receiver": {
                          "type": "string"
                        },
                        "resource": {
                          "type": "string"
                        }
                      }
                    },
                    "mpp": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "integer",
                          "example": 1
                        },
                        "method": {
                          "type": "string",
                          "example": "stripe"
                        },
                        "intent": {
                          "type": "string",
                          "example": "charge"
                        },
                        "currency": {
                          "type": "string",
                          "example": "usd"
                        },
                        "amount_cents": {
                          "type": "integer",
                          "example": 1200
                        },
                        "resource": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "description": "requires x402 or MPP identity header (no payment needed for balance check).\n\nreturns null balance for API key users (they don't use credits).",
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "description": "API key (Bearer is_live_...) or x402 payment header (PAYMENT-SIGNATURE/X-PAYMENT, base64 challenge response).",
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "tags": [
          "agent credits"
        ],
        "summary": "purchase 5 credits with x402 or MPP payment",
        "operationId": "createCredit",
        "security": [
          {
            "apiKey": []
          },
          {
            "agentPaymentAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "data": {
                      "$ref": "#/components/schemas/CreditPurchaseResult"
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "example": {
                  "success": true,
                  "data": {
                    "balance": 5,
                    "credits_added": 5,
                    "pack": "pack_5"
                  }
                }
              }
            }
          },
          "402": {
            "description": "payment required — agent payment auth (x402 or MPP). campaign creation costs $2.25 via x402 (crypto) or 1 credit ($2.40 effective via MPP credit pack).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "example": "PAYMENT_005"
                        },
                        "message": {
                          "type": "string",
                          "example": "insufficient credits — pay $2.25 USDC per campaign (x402) or buy a 5-credit pack for $12.00 (MPP)"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    },
                    "x402": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "integer",
                          "example": 2
                        },
                        "scheme": {
                          "type": "string",
                          "example": "exact"
                        },
                        "network": {
                          "type": "string",
                          "example": "eip155:8453"
                        },
                        "asset": {
                          "type": "string",
                          "example": "USDC"
                        },
                        "amount": {
                          "type": "string",
                          "example": "2.25"
                        },
                        "receiver": {
                          "type": "string"
                        },
                        "resource": {
                          "type": "string"
                        }
                      }
                    },
                    "mpp": {
                      "type": "object",
                      "properties": {
                        "version": {
                          "type": "integer",
                          "example": 1
                        },
                        "method": {
                          "type": "string",
                          "example": "stripe"
                        },
                        "intent": {
                          "type": "string",
                          "example": "charge"
                        },
                        "currency": {
                          "type": "string",
                          "example": "usd"
                        },
                        "amount_cents": {
                          "type": "integer",
                          "example": 1200
                        },
                        "resource": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "PAYMENT_007: purchase failed after payment (contact support)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "example": false
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "description": "credit packs: 5 credits for $12.00 (MPP only). x402 agents pay per-campaign ($2.25) at POST /campaigns.\n\nx402 agents can pay per-campaign ($2.25) by replaying POST /campaigns with a PAYMENT-SIGNATURE header (x402 v2). MPP agents must use packs.\n\ncredits never expire. send PAYMENT-SIGNATURE (x402 v2) or Authorization: Payment (MPP) header.",
        "x-payment-info": {
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0"
          },
          "protocols": [
            {
              "x402": {}
            }
          ]
        },
        "parameters": [
          {
            "name": "Authorization",
            "in": "header",
            "required": true,
            "description": "API key (Bearer is_live_...) or x402 payment header (PAYMENT-SIGNATURE/X-PAYMENT, base64 challenge response).",
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key starting with is_live_. Create at https://www.iris-ai.dev/settings under API keys."
      },
      "agentPaymentAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-PAYMENT",
        "description": "agent payment auth. supports x402 (X-PAYMENT or PAYMENT-SIGNATURE header with base64-encoded payment proof) and MPP (Authorization: Payment header with Stripe credential). POST /campaigns costs $2.25 USDC via x402 or 1 credit ($2.40 effective via MPP credit pack at POST /agent/credits). see https://www.x402.org for x402 details."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "example": "SERVER_001"
              },
              "message": {
                "type": "string",
                "example": "internal server error"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        }
      },
      "CountByStatus": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "by_status": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        },
        "required": [
          "total",
          "by_status"
        ],
        "additionalProperties": false,
        "id": "CountByStatus"
      },
      "Campaign": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "objective_type": {
            "type": "string"
          },
          "product_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "product_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "product_description": {
            "type": [
              "string",
              "null"
            ]
          },
          "follow_up_enabled": {
            "type": "boolean"
          },
          "follow_up_max_count": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "follow_up_delay_days": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "user_id",
          "name",
          "status",
          "objective_type",
          "product_name",
          "product_url",
          "product_description",
          "follow_up_enabled",
          "follow_up_max_count",
          "follow_up_delay_days",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "TargetProfile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "campaign_id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "profile_type": {
            "type": "string"
          },
          "fit_score": {
            "type": [
              "number",
              "null"
            ]
          },
          "job_titles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "industries": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pain_points": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "buying_signals": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "discovery_keywords": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "recommended_channels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "campaign_id",
          "name",
          "profile_type",
          "fit_score",
          "job_titles",
          "industries",
          "pain_points",
          "buying_signals",
          "discovery_keywords",
          "recommended_channels",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "CampaignUsage": {
        "type": "object",
        "properties": {
          "campaign_id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "total_contacts": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "total_conversations": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "delivery_status": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        },
        "required": [
          "campaign_id",
          "status",
          "total_contacts",
          "total_conversations",
          "delivery_status"
        ],
        "additionalProperties": false
      },
      "CampaignContact": {
        "type": "object",
        "properties": {
          "contacts": {}
        },
        "additionalProperties": {}
      },
      "Contact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "first_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "company_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "job_title": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "website": {
            "type": [
              "string",
              "null"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "enrichment_data": {},
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "deleted_at": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "user_id",
          "email",
          "first_name",
          "last_name",
          "company_name",
          "job_title",
          "phone",
          "website",
          "tags",
          "enrichment_data",
          "created_at",
          "updated_at",
          "deleted_at"
        ],
        "additionalProperties": false
      },
      "ContactUsage": {
        "type": "object",
        "properties": {
          "total_contacts": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "period_contacts": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "period_limit": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "period_start": {
            "type": "string"
          },
          "period_end": {
            "type": "string"
          }
        },
        "required": [
          "total_contacts",
          "period_contacts",
          "period_limit",
          "period_start",
          "period_end"
        ],
        "additionalProperties": false
      },
      "BulkContactImportResult": {
        "type": "object",
        "properties": {
          "created": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "updated": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "failed": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "user_id": {
                  "type": "string"
                },
                "email": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "first_name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "last_name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "company_name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "job_title": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "phone": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "website": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "tags": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "enrichment_data": {},
                "created_at": {
                  "type": "string"
                },
                "updated_at": {
                  "type": "string"
                },
                "deleted_at": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "id",
                "user_id",
                "email",
                "first_name",
                "last_name",
                "company_name",
                "job_title",
                "phone",
                "website",
                "tags",
                "enrichment_data",
                "created_at",
                "updated_at",
                "deleted_at"
              ],
              "additionalProperties": false
            }
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "email": {
                  "type": "string"
                },
                "error": {
                  "type": "string"
                }
              },
              "required": [
                "email",
                "error"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "created",
          "updated",
          "failed",
          "contacts",
          "errors"
        ],
        "additionalProperties": false
      },
      "BulkContactDeleteResult": {
        "type": "object",
        "properties": {
          "deletedCount": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "affectedCampaignIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "totalArchivedConversations": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "deletedCount",
          "affectedCampaignIds",
          "totalArchivedConversations"
        ],
        "additionalProperties": false
      },
      "Conversation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "campaign_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "contact_id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "channel": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "metadata": {},
          "contacts": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "full_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "company_name": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "full_name",
              "email",
              "company_name"
            ],
            "additionalProperties": false
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "campaign_id",
          "contact_id",
          "user_id",
          "channel",
          "status",
          "metadata",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "ConversationDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "campaign_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "contact_id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "channel": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "metadata": {},
          "contacts": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "full_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "company_name": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "full_name",
              "email",
              "company_name"
            ],
            "additionalProperties": false
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "conversation_id": {
                  "type": "string"
                },
                "direction": {
                  "type": "string"
                },
                "channel": {
                  "type": "string"
                },
                "content": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                },
                "metadata": {},
                "created_at": {
                  "type": "string"
                },
                "updated_at": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "conversation_id",
                "direction",
                "channel",
                "content",
                "status",
                "metadata",
                "created_at",
                "updated_at"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "id",
          "campaign_id",
          "contact_id",
          "user_id",
          "channel",
          "status",
          "metadata",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "Message": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "conversation_id": {
            "type": "string"
          },
          "direction": {
            "type": "string"
          },
          "channel": {
            "type": "string"
          },
          "content": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "metadata": {},
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "conversation_id",
          "direction",
          "channel",
          "content",
          "status",
          "metadata",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "EngagementMetrics": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "unread": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "by_status": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          },
          "by_channel": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        },
        "required": [
          "total",
          "unread",
          "by_status",
          "by_channel"
        ],
        "additionalProperties": false
      },
      "MarkConversationReadResult": {
        "type": "object",
        "properties": {
          "unread_count": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "contact_id": {
            "type": "string"
          },
          "already_read": {
            "type": "boolean"
          }
        },
        "required": [
          "unread_count",
          "contact_id",
          "already_read"
        ],
        "additionalProperties": false
      },
      "PendingMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "campaign_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "conversation_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "contact_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "channel": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "subject": {
            "type": [
              "string",
              "null"
            ]
          },
          "body": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "status",
          "created_at"
        ],
        "additionalProperties": {}
      },
      "ApproveMessageResult": {
        "type": "object",
        "properties": {
          "sent": {
            "type": "boolean"
          },
          "message_id": {
            "type": "string"
          },
          "channel": {
            "type": "string"
          },
          "contact_id": {
            "type": "string"
          }
        },
        "required": [
          "sent",
          "message_id",
          "channel"
        ],
        "additionalProperties": false
      },
      "RejectMessageResult": {
        "type": "object",
        "properties": {
          "message_id": {
            "type": "string"
          },
          "contact_id": {
            "type": "string"
          }
        },
        "required": [
          "message_id"
        ],
        "additionalProperties": false
      },
      "RetryMessageResult": {
        "type": "object",
        "properties": {
          "retried_count": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "contact_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "retried_count",
          "contact_ids"
        ],
        "additionalProperties": false
      },
      "MessageFeedbackResult": {
        "type": "object",
        "properties": {
          "feedback_id": {
            "type": "string"
          },
          "revised_subject": {
            "type": "string"
          },
          "revised_body": {
            "type": "string"
          },
          "approval_queue_id": {
            "type": "string"
          },
          "message_id": {
            "type": "string"
          }
        },
        "required": [
          "feedback_id",
          "revised_subject",
          "revised_body"
        ],
        "additionalProperties": false
      },
      "BulkMessageActionResult": {
        "type": "object",
        "properties": {
          "affected_count": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "contact_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "skipped_count": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "affected_count",
          "contact_ids"
        ],
        "additionalProperties": false
      },
      "AiUsage": {
        "type": "object",
        "properties": {
          "billing_period_start": {
            "type": "string"
          },
          "billing_period_end": {
            "type": "string"
          },
          "total_generations": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "total_tokens": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "by_generation_type": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        },
        "required": [
          "billing_period_start",
          "billing_period_end",
          "total_generations",
          "total_tokens",
          "by_generation_type"
        ],
        "additionalProperties": false
      },
      "AiGenerateResult": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "content": {
            "type": "string"
          }
        },
        "additionalProperties": {}
      },
      "AiGenerateCampaignResult": {
        "type": "object",
        "properties": {},
        "additionalProperties": {}
      },
      "AiAnalyzeResult": {
        "type": "object",
        "properties": {
          "intent_type": {
            "type": "string"
          },
          "sentiment": {
            "type": "string"
          },
          "key_points": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "suggested_response": {
            "type": "string"
          },
          "requires_human_review": {
            "type": "boolean"
          },
          "extracted_data": {}
        },
        "required": [
          "intent_type",
          "sentiment",
          "key_points",
          "suggested_response",
          "requires_human_review",
          "extracted_data"
        ],
        "additionalProperties": false
      },
      "DiscoveryJobHandle": {
        "type": "object",
        "properties": {
          "job_id": {
            "type": "string"
          }
        },
        "required": [
          "job_id"
        ],
        "additionalProperties": false
      },
      "DiscoveryJob": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "progress_percent": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "progress_message": {
            "type": [
              "string",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "contact_count": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "contacts": {
            "type": [
              "array",
              "null"
            ],
            "items": {}
          }
        },
        "required": [
          "id",
          "status",
          "progress_percent",
          "progress_message",
          "error",
          "started_at",
          "completed_at",
          "created_at",
          "updated_at",
          "contact_count",
          "contacts"
        ],
        "additionalProperties": false
      },
      "DiscoverySource": {
        "type": "object",
        "properties": {
          "source_type": {
            "type": "string"
          },
          "apify_actor_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "display_name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_enabled": {
            "type": "boolean"
          },
          "cost_per_thousand": {
            "type": [
              "number",
              "null"
            ]
          },
          "supported_icp_types": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "priority": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "source_type",
          "apify_actor_id",
          "display_name",
          "description",
          "is_enabled",
          "cost_per_thousand",
          "supported_icp_types",
          "priority"
        ],
        "additionalProperties": false
      },
      "AnalyticsOverview": {
        "type": "object",
        "properties": {
          "campaigns": {
            "$ref": "#/components/schemas/CountByStatus"
          },
          "contacts": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            },
            "required": [
              "total"
            ],
            "additionalProperties": false
          },
          "conversations": {
            "$ref": "#/components/schemas/CountByStatus"
          },
          "messages": {
            "$ref": "#/components/schemas/CountByStatus"
          }
        },
        "required": [
          "campaigns",
          "contacts",
          "conversations",
          "messages"
        ],
        "additionalProperties": false
      },
      "CampaignAnalytics": {
        "type": "object",
        "properties": {
          "campaign": {},
          "contacts": {
            "$ref": "#/components/schemas/CountByStatus"
          },
          "conversations": {
            "$ref": "#/components/schemas/CountByStatus"
          },
          "messages": {
            "$ref": "#/components/schemas/CountByStatus"
          },
          "delivery_status": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        },
        "required": [
          "campaign",
          "contacts",
          "conversations",
          "messages",
          "delivery_status"
        ],
        "additionalProperties": false
      },
      "PerformanceMetrics": {
        "type": "object",
        "properties": {
          "days": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "time_series": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string"
                }
              },
              "required": [
                "date"
              ],
              "additionalProperties": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              }
            }
          }
        },
        "required": [
          "days",
          "time_series"
        ],
        "additionalProperties": false
      },
      "ResponseTimeMetrics": {
        "type": "object",
        "properties": {
          "total_conversations": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "conversations_with_replies": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "reply_rate": {
            "type": "number"
          },
          "average_response_time_ms": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "average_response_time_hours": {
            "type": "number"
          },
          "median_response_time_ms": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "median_response_time_hours": {
            "type": "number"
          }
        },
        "required": [
          "total_conversations",
          "conversations_with_replies",
          "reply_rate",
          "average_response_time_ms",
          "average_response_time_hours",
          "median_response_time_ms",
          "median_response_time_hours"
        ],
        "additionalProperties": false
      },
      "ContactTypeDistribution": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "by_source": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        },
        "required": [
          "total",
          "by_source"
        ],
        "additionalProperties": false
      },
      "BillingPlan": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "plan_name": {
            "type": "string"
          },
          "display_name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "monthly_price_cents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "yearly_price_cents": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "campaigns_per_period": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "contacts_per_campaign": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "messages_per_campaign": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "stripe_monthly_price_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "stripe_yearly_price_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_active": {
            "type": "boolean"
          },
          "sort_order": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "plan_name",
          "display_name",
          "description",
          "monthly_price_cents",
          "yearly_price_cents",
          "campaigns_per_period",
          "contacts_per_campaign",
          "messages_per_campaign",
          "stripe_monthly_price_id",
          "stripe_yearly_price_id",
          "is_active",
          "sort_order",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "ConnectedAccount": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "channel": {
            "type": "string"
          },
          "platform_username": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "channel",
          "platform_username",
          "status",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "ChannelAvailability": {
        "type": "object",
        "properties": {
          "channel": {
            "type": "string"
          },
          "available": {
            "type": "boolean"
          },
          "connected": {
            "type": "boolean"
          }
        },
        "required": [
          "channel",
          "available",
          "connected"
        ],
        "additionalProperties": false
      },
      "SendChannelMessageResult": {
        "type": "object",
        "properties": {
          "deliveryResult": {
            "type": "object",
            "properties": {
              "success": {
                "type": "boolean"
              },
              "channel": {
                "type": "string"
              },
              "platformMessageId": {
                "type": "string"
              },
              "platformConversationId": {
                "type": "string"
              },
              "error": {
                "type": "string"
              },
              "errorCode": {
                "type": "string"
              },
              "retryable": {
                "type": "boolean"
              },
              "retryAfter": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "sentAt": {
                "type": "string"
              },
              "metadata": {}
            },
            "required": [
              "success",
              "channel"
            ],
            "additionalProperties": {}
          },
          "contactId": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "deliveryResult",
          "contactId"
        ],
        "additionalProperties": false
      },
      "Notification": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "read": {
            "type": "boolean"
          },
          "metadata": {},
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "user_id",
          "type",
          "title",
          "message",
          "read",
          "metadata",
          "created_at"
        ],
        "additionalProperties": false
      },
      "MarkAllNotificationsReadResult": {
        "type": "object",
        "properties": {
          "updated_count": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          }
        },
        "required": [
          "updated_count"
        ],
        "additionalProperties": false
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "key_prefix": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "last_used_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "revoked_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "user_id",
          "name",
          "key_prefix",
          "scopes",
          "last_used_at",
          "expires_at",
          "created_at"
        ],
        "additionalProperties": false
      },
      "CreateApiKeyResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "key_prefix": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "last_used_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "revoked_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "key": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "user_id",
          "name",
          "key_prefix",
          "scopes",
          "last_used_at",
          "expires_at",
          "created_at",
          "key"
        ],
        "additionalProperties": false
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "user_id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "active": {
            "type": "boolean"
          },
          "secret": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "user_id",
          "url",
          "events",
          "description",
          "active",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "webhook_id": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "payload": {},
          "response_status": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "response_body": {
            "type": [
              "string",
              "null"
            ]
          },
          "attempt_count": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "next_retry_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "delivered_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "failed_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "webhook_id",
          "event_type",
          "payload",
          "response_status",
          "response_body",
          "attempt_count",
          "next_retry_at",
          "delivered_at",
          "failed_at",
          "created_at"
        ],
        "additionalProperties": false
      },
      "TestWebhookResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "delivery_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "response_status": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "response_body": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "success",
          "delivery_id",
          "response_status",
          "response_body"
        ],
        "additionalProperties": false
      },
      "RotateSecretResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "secret": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "secret"
        ],
        "additionalProperties": false
      },
      "CreditBalance": {
        "type": "object",
        "properties": {
          "balance": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "identity_id": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "balance"
        ],
        "additionalProperties": false
      },
      "CreditPurchaseResult": {
        "type": "object",
        "properties": {
          "balance": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "credits_added": {
            "type": "integer",
            "minimum": -9007199254740991,
            "maximum": 9007199254740991
          },
          "pack": {
            "type": "string"
          }
        },
        "required": [
          "balance",
          "credits_added",
          "pack"
        ],
        "additionalProperties": false
      },
      "EmptyResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "null"
          }
        },
        "required": [
          "data"
        ],
        "additionalProperties": false
      }
    }
  }
}