NAV

Introduction

Welcome to the Kayse Public API documentation! Our API enables you to interact with Kayse's endpoints, providing access to various functionalities available on our platform.

On the left, you'll find detailed information about each endpoint, including descriptions, methods, URLs, and request/response schemas. The right side features example requests (via cURL) and corresponding JSON responses. We plan to expand this documentation with additional endpoints to offer comprehensive access to the Kayse database.

If this is your first time using our API, start by reviewing the Authentication section to learn how to obtain and use API keys.

For updates and changes, refer to the Changelog section.

Authentication

The Kayse API uses API keys to authenticate requests to its endpoints. You can generate new API keys in your company settings under the "API Keys" section.

API Key Management

You can create multiple API keys, each with a custom name for easy identification. If you no longer need an API key, you can disable it through the dashboard without affecting your other keys.

Including Your API Key

Include your API key in all requests to the Kayse API using the following method:

Header Authentication: X-API-KEY: your_api_key_here

Rate Limiting

All Kayse APIs enforce rate limiting. Each API key is allowed up to 500 requests per hour. Once the rate limit is reached, the server will respond with HTTP Status 429 - Too Many Requests.

Rate-limiting details are included in the response headers:

Currently, rate limiting is not applied on a per-user basis, but this may be introduced in future updates.

Errors

The Kayse API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is incorrect.
404 Not Found -- The specified item could not be found.
405 Method Not Allowed -- You tried to access the API with an invalid method.
429 Too Many Requests -- You're making too many requests.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

Clients

Create a new client

curl --location --request POST 'https://api.kayse.com/v1/clients' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "email": "john.doe@example.com",
    "mobile": "+1234567890",
    "external_source": "manual",
    "external_source_id": "ext_123",
    "first_name": "John",
    "last_name": "Doe",
    "date_of_birth": "1990-01-15",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "address_line1": "123 Main St",
    "address_line2": "Apt 4B",
    "date_of_death": null,
    "meta": {
        "notes": "Client prefers email communication",
        "source": "website"
    },
    "case_ids": [12345, 67890]
}'

HTTP Request

POST https://api.kayse.com/v1/clients

The above command returns JSON structured like this:

{
    "id": 123,
    "email": "john.doe@example.com",
    "mobile": "+1234567890",
    "external_source": "manual",
    "external_source_id": "ext_123",
    "first_name": "John",
    "last_name": "Doe",
    "gender": "male",
    "date_of_birth": "1990-01-15",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "address_line1": "123 Main St",
    "address_line2": "Apt 4B",
    "voice_calls_opted_out": false,
    "date_of_death": null,
    "meta": {
        "notes": "Client prefers email communication",
        "source": "website"
    },
    "case_ids": [12345, 67890]
}

Request Body Fields

Field Required Type Description
email false String Client's email address
mobile false String Client's mobile phone number
external_source true String Source system identifier (e.g., "manual", "import")
external_source_id true String Unique identifier from external source
first_name true String Client's first name
last_name true String Client's last name
date_of_birth false Date Client's date of birth (YYYY-MM-DD format)
city false String City of residence
state false String State of residence
postal_code false String Postal/ZIP code
address_line1 false String Primary address line
address_line2 false String Secondary address line
date_of_death false Date Date of death (YYYY-MM-DD format)
meta false Object Additional metadata as key-value pairs
case_id false Integer Associated case ID

Get a client by ID

curl --location --request GET 'https://api.kayse.com/v1/clients/123' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}'

HTTP Request

GET https://api.kayse.com/v1/clients/{id}

The above command returns JSON structured like this:

{
    "id": 123,
    "email": "john.doe@example.com",
    "mobile": "+1234567890",
    "external_source": "manual",
    "external_source_id": "ext_123",
    "first_name": "John",
    "last_name": "Doe",
    "gender": "male",
    "date_of_birth": "1990-01-15",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "address_line1": "123 Main St",
    "address_line2": "Apt 4B",
    "date_of_death": null,
    "meta": {
        "notes": "Client prefers email communication",
        "source": "website"
    }
}

URL Parameters

Field Required Type Description
id true Integer The unique identifier of the client

Update a client

curl --location --request PUT 'https://api.kayse.com/v1/clients/123' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "email": "john.doe.updated@example.com",
    "mobile": "+1234567890",
    "city": "Los Angeles",
    "state": "CA",
    "postal_code": "90210",
    "address_line1": "456 Oak Ave",
    "meta": {
        "notes": "Updated contact information",
        "source": "website"
    },
    "case_ids": [12345, 67890]
}'

HTTP Request

PUT https://api.kayse.com/v1/clients/{id}

The above command returns JSON structured like this:

{
    "id": 123,
    "email": "john.doe.updated@example.com",
    "mobile": "+1234567890",
    "external_source": "manual",
    "external_source_id": "ext_123",
    "first_name": "John",
    "last_name": "Doe",
    "gender": "male",
    "date_of_birth": "1990-01-15",
    "city": "Los Angeles",
    "state": "CA",
    "postal_code": "90210",
    "address_line1": "456 Oak Ave",
    "address_line2": "Apt 4B",
    "voice_calls_opted_out": false,
    "date_of_death": null,
    "meta": {
        "notes": "Updated contact information",
        "source": "website"
    },
    "case_ids": [12345, 67890]
}

URL Parameters

Field Required Type Description
id true Integer The unique identifier of the client

Request Body Fields

Keep in mind that this is a PUT endpoint (NOT PATCH), and thus all optional fields that were ommited will be set as null.

Field Required Type Description
email false String Client's email address
mobile false String Client's mobile phone number
external_source true String Source system identifier (e.g., "manual", "import")
external_source_id true String Unique identifier from external source
first_name true String Client's first name
last_name true String Client's last name
date_of_birth false Date Client's date of birth (YYYY-MM-DD format)
city false String City of residence
state false String State of residence
postal_code false String Postal/ZIP code
address_line1 false String Primary address line
address_line2 false String Secondary address line
date_of_death false Date Date of death (YYYY-MM-DD format)
meta false Object Additional metadata as key-value pairs
case_ids false Array Associated case IDs (replaces links on create/update)

Delete a client

curl --location --request DELETE 'https://api.kayse.com/v1/clients/123' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}'

HTTP Request

DELETE https://api.kayse.com/v1/clients/{id}

The above command returns JSON structured like this:

{
    "message": "client deleted successfully"
}

URL Parameters

Field Required Type Description
id true Integer The unique identifier of the client

Bulk upsert clients

curl --location --request POST 'https://api.kayse.com/v1/clients/bulk' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "clients": [
    {
      "email": "new.client@example.com",
      "external_source": "manual",
      "external_source_id": "external-901",
      "first_name": "New",
      "last_name": "Client",
      "case_ids": [12345]
    },
    {
      "id": 123,
      "external_source": "manual",
      "external_source_id": "external-123",
      "first_name": "John",
      "last_name": "Doe",
      "voice_calls_opted_out": true
    }
  ]
}'

HTTP Request

POST https://api.kayse.com/v1/clients/bulk

The above command returns JSON structured like this (per client):

{
  "clients": [
    {
      "id": 999,
      "email": "new.client@example.com",
      "external_source": "manual",
      "external_source_id": "external-901",
      "first_name": "New",
      "last_name": "Client",
      "case_ids": [12345]
    },
    {
      "id": 123,
      "first_name": "John",
      "last_name": "Doe",
      "voice_calls_opted_out": true
    }
  ]
}

Each entry in the clients array adheres to the same schema as the single create endpoint. Providing an id updates an existing record, while omitting it creates a new client. Validation failures abort the entire batch and return the corresponding error.

Request Body Fields

Field Required Type Description
clients true Array<Object> Array of client payloads. Omit id to create a client; include id to update.
clients[].id false Integer Client ID to update.
clients[].case_ids false Array<Integer> Optional case IDs to associate.
clients[].voice_calls_opted_out false Boolean Apply the opt-out flag across linked clients/cases when set.
clients[...fields] varies Mixed Remaining fields follow the single-client create schema (email, mobile, first_name, etc.).

Cases

Create a new case

curl --location --request POST 'https://api.kayse.com/v1/cases' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "case_number": "CASE-2024-001",
    "external_source": "other",
    "external_source_id": "ext_case_123",
    "external_source_data": {
        "court_id": "NYC001",
        "filing_date": "2024-01-15",
        "case_type": "civil"
    },
    "name": "Smith vs. Johnson",
    "court_name": "New York Supreme Court",
    "jurisdiction": "New York",
    "description": "Contract dispute regarding service delivery",
    "status": "active",
    "type": "civil",
    "is_obo": false,
    "created_date": "2024-01-15",
    "court_date": "2024-03-20",
    "end_date": null,
    "client_ids": [123, 456],
    "opt_out_voice_calls": false
}'

HTTP Request

POST https://api.kayse.com/v1/cases

The above command returns JSON structured like this:

{
    "id": 456,
    "case_number": "CASE-2024-001",
    "external_source": "other",
    "external_source_id": "ext_case_123",
    "external_source_data": {
        "court_id": "NYC001",
        "filing_date": "2024-01-15",
        "case_type": "civil"
    },
    "name": "Smith vs. Johnson",
    "court_name": "New York Supreme Court",
    "jurisdiction": "New York",
    "description": "Contract dispute regarding service delivery",
    "status": "active",
    "type": "civil",
    "is_obo": false,
    "created_date": "2024-01-15",
    "court_date": "2024-03-20",
    "end_date": null,
    "client_ids": [123, 456],
    "opt_out_voice_calls": false
}

Request Body Fields

Field Required Type Description
case_number true String Unique case identifier
external_source true String Source system identifier (a static list defined in-app)
external_source_id true String Unique identifier from external source
external_source_data false Object Additional data from external source as key-value pairs
name false String Case name/title
court_name false String Name of the court
jurisdiction false String Legal jurisdiction
description false String Case description
status true String Case status (e.g., "active", "closed", "pending")
type true String Case type (e.g., "civil", "criminal", "family")
is_obo false Boolean Whether case is "on behalf of" another party
created_date false Date Case creation date (YYYY-MM-DD format)
court_date false Date Next court date (YYYY-MM-DD format)
end_date false Date Case end date (YYYY-MM-DD format)
client_ids false Array Associated client IDs (replaces links on create/update)
opt_out_voice_calls false Boolean When true, marks all linked clients voice-calls opted out

Get a case by ID

curl --location --request GET 'https://api.kayse.com/v1/cases/456' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}'

HTTP Request

GET https://api.kayse.com/v1/cases/{id}

The above command returns JSON structured like this:

{
    "id": 456,
    "case_number": "CASE-2024-001",
    "external_source": "other",
    "external_source_id": "ext_case_123",
    "external_source_data": {
        "court_id": "NYC001",
        "filing_date": "2024-01-15",
        "case_type": "civil"
    },
    "name": "Smith vs. Johnson",
    "court_name": "New York Supreme Court",
    "jurisdiction": "New York",
    "description": "Contract dispute regarding service delivery",
    "status": "active",
    "type": "civil",
    "is_obo": false,
    "created_date": "2024-01-15",
    "court_date": "2024-03-20",
    "end_date": null
}

URL Parameters

Field Required Type Description
id true Integer The unique identifier of the case

Update a case

curl --location --request PUT 'https://api.kayse.com/v1/cases/456' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "case_number": "CASE-2024-001",
    "external_source": "other",
    "external_source_id": "ext_case_123",
    "external_source_data": {
        "court_id": "NYC001",
        "filing_date": "2024-01-15",
        "case_type": "civil"
    },
    "name": "Smith vs. Johnson",
    "court_name": "New York Supreme Court",
    "jurisdiction": "New York",
    "description": "Contract dispute regarding service delivery",
    "status": "active",
    "type": "civil",
    "is_obo": false,
    "created_date": "2024-01-15",
    "court_date": "2024-03-20",
    "end_date": null,
    "client_ids": [123, 456],
    "opt_out_voice_calls": true
}'

HTTP Request

PUT https://api.kayse.com/v1/cases/{id}

The above command returns JSON structured like this:

{
    "id": 456,
    "case_number": "CASE-2024-001",
    "external_source": "other",
    "external_source_id": "ext_case_123",
    "external_source_data": {
        "court_id": "NYC001",
        "filing_date": "2024-01-15",
        "case_type": "civil",
        "resolution": "settlement",
        "settlement_amount": 50000
    },
    "name": "Smith vs. Johnson",
    "court_name": "New York Supreme Court",
    "jurisdiction": "New York",
    "description": "Case resolved through settlement",
    "status": "closed",
    "type": "civil",
    "is_obo": false,
    "created_date": "2024-01-15",
    "court_date": "2024-03-20",
    "end_date": "2024-06-15",
    "client_ids": [123, 456],
    "opt_out_voice_calls": true
}

URL Parameters

Field Required Type Description
id true Integer The unique identifier of the case

Request Body Fields

Keep in mind that this is a PUT endpoint (NOT PATCH), and thus all optional fields that were ommited will be set as null.

Field Required Type Description
case_number true String Unique case identifier
external_source true String Source system identifier (a static list defined in-app)
external_source_id true String Unique identifier from external source
external_source_data false Object Additional data from external source as key-value pairs
name false String Case name/title
court_name false String Name of the court
jurisdiction false String Legal jurisdiction
description false String Case description
status true String Case status (e.g., "active", "closed", "pending")
type true String Case type (e.g., "civil", "criminal", "family")
is_obo false Boolean Whether case is "on behalf of" another party
created_date false Date Case creation date (YYYY-MM-DD format)
court_date false Date Next court date (YYYY-MM-DD format)
end_date false Date Case end date (YYYY-MM-DD format)

Delete a case

curl --location --request DELETE 'https://api.kayse.com/v1/cases/456' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}'

HTTP Request

DELETE https://api.kayse.com/v1/cases/{id}

The above command returns JSON structured like this:

{
    "message": "case deleted successfully"
}

URL Parameters

Field Required Type Description
id true Integer The unique identifier of the case

Bulk upsert cases

curl --location --request POST 'https://api.kayse.com/v1/cases/bulk' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "cases": [
    {
      "case_number": "CASE-2024-001",
      "external_source": "other",
      "external_source_id": "external-001",
      "name": "Smith vs Johnson",
      "status": "open",
      "type": "civil",
      "client_ids": [11,22]
    },
    {
      "id": 456,
      "external_source": "other",
      "external_source_id": "external-002",
      "name": "Brown vs Doe",
      "status": "closed",
      "type": "civil",
      "opt_out_voice_calls": true
    }
  ]
}'

HTTP Request

POST https://api.kayse.com/v1/cases/bulk

The above command returns JSON structured like this (per case):

{
  "cases": [
    {
      "id": 789,
      "case_number": "CASE-2024-001",
      "name": "Smith vs Johnson",
      "status": "open",
      "type": "civil",
      "client_ids": [11,22]
    },
    {
      "id": 456,
      "name": "Brown vs Doe",
      "status": "closed",
      "type": "civil",
      "opt_out_voice_calls": true
    }
  ]
}

Each object in the cases array follows the same schema as the create endpoint. When an id is omitted the case is created; when id is provided the case is updated atomically with the same validation rules as the PUT endpoint. Validation errors stop the batch and return the first error encountered.

Request Body Fields

Field Required Type Description
cases true Array<Object> Array of case payloads. Omit id to create; include id to update an existing case.
cases[].id false Integer Case ID to update.
cases[].client_ids false Array<Integer> Optional list of client IDs to associate. Same validation rules as the create endpoint.

All other fields inside each object follow the single-case create schema (case_number, status, type, opt_out_voice_calls, etc.). | cases[].id | false | Integer | Case ID to update. | | cases[].client_ids | false | Array<Integer> | Optional list of client IDs to associate. Same validation rules as the create endpoint. |

Bulk delete cases

curl --location --request POST 'https://api.kayse.com/v1/cases/bulk_delete' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "ids": [456, 789, 790],
  "with_clients": false
}'

HTTP Request

POST https://api.kayse.com/v1/cases/bulk_delete

Request Body Fields

Field Required Type Description
ids true Array Case IDs to delete (max 500 per request)
with_clients false Boolean When true, also deletes any clients that are exclusively linked to the case

Successful responses return deleted_ids with the list of IDs that were removed and audit logs are emitted per case.

Send SMS to Client + Case

curl --location --request POST 'https://api.kayse.com/v1/cases/communication/sms' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "case_id": 123,
    "client_id": 123,
    "message": "hello from kayse"
}'

The above command returns JSON structured like this:

{
    "message": "sms scheduled"
}

Request Body Fields

Field Required Type Description
case_id true Integer Unique case identifier
client_id true Integer Unique cliet identifier
message true String Message to be sent, may contain Kayse template variables

Send Email to Client + Case

curl --location --request POST 'https://api.kayse.com/v1/cases/communication/email' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "case_id": 123,
    "client_id": 123,
    "subject": "hello from kayse",
    "message": "hello from kayse"
}'

The above command returns JSON structured like this:

{
    "message": "email scheduled"
}

Request Body Fields

Field Required Type Description
case_id true Integer Unique case identifier
client_id true Integer Unique cliet identifier
subject true String Subject of the email to be sent
message true String Message to be sent, may contain Kayse template variables

Case Lists

Case lists allow you to save reusable case filters that power campaigns and autom autom automations. The endpoints below mirror the public API routes exposed under /v1/case_lists.

List case lists

curl --location --request GET 'https://api.kayse.com/v1/case_lists?key=mass+tort' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}'

HTTP Request

GET https://api.kayse.com/v1/case_lists

Query Parameters

Field Required Type Description
key false String Optional search term applied to the case list name
page false Int Page number (defaults to 1)
page_size false Int Results per page (defaults to 25, max 100)
hide_empty false Bool When true, only returns lists that currently contain case IDs

Create a case list

curl --location --request POST 'https://api.kayse.com/v1/case_lists' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "name": "Mass Tort Prospects",
  "description": "Prospects that match tort filters",
  "filter": {
    "case_type_ids": [25],
    "status_ids": [30]
  },
  "include_ids": [101, 102],
  "exclude_ids": [],
  "is_obo": false
}'

HTTP Request

POST https://api.kayse.com/v1/case_lists

Request Body Fields

Field Required Type Description
name true String Case list name
description false String Optional description shown in the UI
filter false Object Case filter object using the same keys as /v1/cases (status_ids, case_type_ids, etc.)
include_ids false Array Explicit case IDs to include. Requires filter to be present
exclude_ids false Array Explicit case IDs to exclude. Requires filter to be present
is_obo false Boolean When set, propagates the "on behalf of" flag to member cases via bulk update

Bulk upsert case lists

curl --location --request POST 'https://api.kayse.com/v1/case_lists/bulk' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "lists": [
    {
      "name": "PI Prospects",
      "description": "Personal injury prospects",
      "filter": { "case_type_ids": [10], "status_ids": [4] },
      "include_ids": [200, 250]
    },
    {
      "id": 55,
      "name": "Mass Tort Prospects",
      "is_obo": true,
      "filter": { "case_type_ids": [25] }
    }
  ]
}'

HTTP Request

POST https://api.kayse.com/v1/case_lists/bulk

Request Body Fields

Field Required Type Description
lists true Array<Object> Array containing new or existing case list definitions. Omit id to create, provide id to update.

Each object inside lists accepts the same fields as the create endpoint. When an id is provided the name/description/is_obo fields are updated and the filter is re-applied with the equivalent of a "set" action (existing members are replaced with the new filter result plus include/exclude overrides). Responses contain the resulting IDs and action ("created" or "updated").

Calls

Schedule New AI Call

curl --location --request POST 'https://public-api.kayse.ai/v1/calls' \
--header 'accept: application/json' \
--header 'X-Public-Api-Key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    'campaign_id': 123,
    'case_id': 123
}'

HTTP Request

POST https://public-api.kayse.ai/v1/calls

The above command returns JSON structured like this:

{
  "campaign_id": 123,
  "client_id": 123,
  "case_id": 123
}

Request Body Fields

Field Required Type Description
campaign_id true Integer Unique campaign identifier
case_id true String Source system identifier (a static list defined in-app)

Campaigns

Create Campaign

curl --location --request POST 'https://public-api.kayse.ai/v1/calls' \
--header 'accept: application/json' \
--header 'X-Public-Api-Key: {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "Test",
    "agent_id": "abc_123123",
    "case_list_id": 123,
    "start_time": "2006-01-02T15:04:05Z07:00",
    "end_time": "2006-01-02T15:04:05Z07:00", 

    "callback_delays": [
        {
            "minutes": 1,
            "hours": 0,
            "days": 0
        }
    ],
    "days": ["Monday", "Tuesday"],

    "send_sms_before_call_delay_minutes": 15,
    "send_sms_before_call": true,
    "sms_before_call_text": "test test",
    "send_sms_after_successful_call": true,
    "sms_after_successful_call_text": "test test",
    "send_sms_after_failed_call": true,
    "sms_after_failed_call_text": "test test",

    "is_obo": false,

    "calls_scheduled_externally": true, 
}'

HTTP Request

POST https://api.kayse.com/v1/campaigns

The above command returns JSON structured like this:

{
    "name": "Test",
    "agent_id": "abc_123123",
    "case_list_id": 123,
    "case_list_name": "test test test",
    "start_time": "2006-01-02T15:04:05Z07:00",
    "end_time": "2006-01-02T15:04:05Z07:00", 
    "agent": {
        "id": 123,
        "name": "karen",
        "voice_id": "abc_123",
        "avatar_url": "https://host.com/img.png",
    },

    "stats": {
        "call_id_123": {
            "total_calls": 132,
            "finished_calls": 120,
            "called_clients": 95,
            "total_clients": 100,
            "success_calls": 85,
            "success_calls_percentage": 70.8,
            "failed_calls": 35,
            "failed_calls_percentage": 29.2,
            "average_sentiment_score": 0.76,
            "average_call_duration": "04:35",
            "total_call_duration": "12:20",
            "disqualified_clients": 5,
            "disqualification_rate": 5.0,
            "converted_clients": 40,
            "conversion_rate": 42.1,
            "in_progress_rate": 12.5
        }
    },

    "callback_delays": [
        {
            "minutes": 1,
            "hours": 0,
            "days": 0
        }
    ],
    "days": ["Monday", "Tuesday"],

    "send_sms_before_call_delay_minutes": 15,
    "send_sms_before_call": true,
    "sms_before_call_text": "test test",
    "send_sms_after_successful_call": true,
    "sms_after_successful_call_text": "test test",
    "send_sms_after_failed_call": true,
    "sms_after_failed_call_text": "test test",

    "is_obo": false,

    "calls_scheduled_externally": true, 
}

Request Body Fields

Field Required Type Description
name true String Campaign name
agent_id true String ID of AI agent that's being used by the campaign
case_list_id true String ID of cases that this campaigns operates on
start_time false Object Time of day to start the campaign execution
end_time false String Time of day to end the campaign execution
callback_delays false []Object Delays used to retry calls on failure
days false String Weekdays on which campaign should be executed
send_sms_before_call_delay_minutes false String Number of minutes to send sms before call
send_sms_before_call true String Whether to send sms before call
sms_before_call_text true String Sms before call message text
send_sms_after_successful_call false Boolean Whether to send sms after successful call
sms_after_successful_call_text false Date Sms after successful call message text
send_sms_after_failed_call false Date Whether to send sms after failed call
sms_after_failed_call_text false Date Sms after failed call message text
is_obo false Boolean Identifies whether campaign is based on obo clients
calls_scheduled_externally false Boolean identifies whether calls are scheduled from outside Kayse

List Campaigns

curl --location --request GET 'https://public-api.kayse.ai/v1/calls' \
--header 'accept: application/json' \
--header 'X-Public-Api-Key: {{apikey}}' \
--header 'Content-Type: application/json'

Query Params

Field Required Type Description
key false String Used for search purposes

HTTP Request

GET https://api.kayse.com/v1/campaigns

The above command returns JSON structured like this:

[
    {
        "name": "Test",
        "agent_id": "abc_123123",
        "case_list_id": 123,
        "case_list_name": "test test test",
        "start_time": "2006-01-02T15:04:05Z07:00",
        "end_time": "2006-01-02T15:04:05Z07:00", 
        "agent": {
            "id": 123,
            "name": "karen",
            "voice_id": "abc_123",
            "avatar_url": "https://host.com/img.png",
        },

        "stats": {
            "call_id_123": {
                "total_calls": 132,
                "finished_calls": 120,
                "called_clients": 95,
                "total_clients": 100,
                "success_calls": 85,
                "success_calls_percentage": 70.8,
                "failed_calls": 35,
                "failed_calls_percentage": 29.2,
                "average_sentiment_score": 0.76,
                "average_call_duration": "04:35",
                "total_call_duration": "12:20",
                "disqualified_clients": 5,
                "disqualification_rate": 5.0,
                "converted_clients": 40,
                "conversion_rate": 42.1,
                "in_progress_rate": 12.5
            }
        },

        "callback_delays": [
            {
                "minutes": 1,
                "hours": 0,
                "days": 0
            }
        ],
        "days": ["Monday", "Tuesday"],

        "send_sms_before_call_delay_minutes": 15,
        "send_sms_before_call": true,
        "sms_before_call_text": "test test",
        "send_sms_after_successful_call": true,
        "sms_after_successful_call_text": "test test",
        "send_sms_after_failed_call": true,
        "sms_after_failed_call_text": "test test",

        "is_obo": false,

        "calls_scheduled_externally": true, 
    }
] 

Metadata

The metadata endpoint exposes a machine-readable list of public objects (cases, clients, case lists) along with their fields, data types, and whether they are required. This is useful for building dynamic integrations that need to adapt to new fields as they become available.

List objects and fields

curl --location --request GET 'https://api.kayse.com/v1/metadata/objects' \
--header 'accept: application/json' \
--header 'x-api-key: {{apikey}}'

HTTP Request

GET https://api.kayse.com/v1/metadata/objects

The above command returns JSON structured like this:

[
  {
    "name": "cases",
    "fields": [
      {
        "name": "case_number",
        "type": "string",
        "required": false,
        "description": "Unique case identifier"
      },
      {
        "name": "status",
        "type": "string",
        "required": true,
        "description": "Case status (created if missing)"
      }
    ]
  },
  {
    "name": "clients",
    "fields": [
      {
        "name": "email",
        "type": "string",
        "required": false,
        "description": "Primary email"
      }
    ]
  },
  {
    "name": "case_lists",
    "fields": [
      {
        "name": "name",
        "type": "string",
        "required": true,
        "description": "List name"
      },
      {
        "name": "filter",
        "type": "object",
        "required": false,
        "description": "Saved case filter"
      }
    ]
  }
]

Response Fields

Field Type Description
name String Object name (e.g., cases, clients, case_lists)
fields Array<Field> List of fields belonging to the object
fields[].name String Field name as accepted by the API
fields[].type String Data type (string, uint, bool, date, object, etc.)
fields[].required Boolean Indicates whether the field is required on create
fields[].description String Human-friendly description of the field

The endpoint is cached and changes whenever new public fields are added so integrations can refresh their local schema instead of tracking changes manually.