MENU navbar-image

Introduction

This documentation aims to provide all the information you need to work with our API.

<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>

Authenticating requests

To authenticate requests, include a X-API-Key header with the value "{YOUR_AUTH_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

You can retrieve your token by visiting your dashboard and clicking Generate API token.

Bill Rates

APIs for managing user bill rates within projects.

Bill rates represent the hourly rate for a user on a specific project, effective from a given start date. Each user can have multiple bill rates over time, but only one active rate at any given time.

Display a paginated list of bill rates for a user in a project.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/projects/1/users/1/bill-rates?per_page=50&sort=started_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/1/users/1/bill-rates"
);

const params = {
    "per_page": "50",
    "sort": "started_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "project_id": 1,
            "user_id": 42,
            "rate": 85.5,
            "started_at": "2024-01-01T00:00:00.000000Z",
            "created_at": "2023-12-15T10:30:00.000000Z",
            "updated_at": "2023-12-15T10:30:00.000000Z",
            "status": "current"
        },
        {
            "id": 2,
            "project_id": 1,
            "user_id": 42,
            "rate": 75,
            "started_at": "2023-07-01T00:00:00.000000Z",
            "created_at": "2023-06-20T14:15:00.000000Z",
            "updated_at": "2023-06-20T14:15:00.000000Z",
            "status": "past"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/projects/1/users/42/bill-rates?page=1",
        "last": "https://example.com/api/v1/projects/1/users/42/bill-rates?page=2",
        "prev": null,
        "next": "https://example.com/api/v1/projects/1/users/42/bill-rates?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 2,
        "path": "https://example.com/api/v1/projects/1/users/42/bill-rates",
        "per_page": 30,
        "to": 30,
        "total": 45
    }
}
 

Example response (403, unauthorized):


{
    "message": "This action is unauthorized."
}
 

Request      

GET api/v1/projects/{project_id}/users/{user_id}/bill-rates

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

project_id   integer   

The ID of the project. Example: 1

user_id   integer   

The ID of the user. Example: 1

project   integer   

The ID of the project. Example: 1

user   integer   

The ID of the user. Example: 42

Query Parameters

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Example: started_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new bill rate for a user in a project.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/projects/1/users/1/bill-rates" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"started_at\": \"2024-01-01\",
    \"rate\": \"85.50\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/1/users/1/bill-rates"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "started_at": "2024-01-01",
    "rate": "85.50"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 3,
    "project_id": 1,
    "user_id": 42,
    "rate": 85.5,
    "started_at": "2024-01-01T00:00:00.000000Z",
    "created_at": "2023-12-20T09:45:00.000000Z",
    "updated_at": "2023-12-20T09:45:00.000000Z",
    "status": "future"
}
 

Example response (403, unauthorized):


{
    "message": "This action is unauthorized."
}
 

Example response (422, duplicate_date):


{
    "message": "The given data was invalid.",
    "errors": {
        "started_at": [
            "The start date already exists for this user."
        ]
    }
}
 

Request      

POST api/v1/projects/{project_id}/users/{user_id}/bill-rates

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

project_id   integer   

The ID of the project. Example: 1

user_id   integer   

The ID of the user. Example: 1

project   integer   

The ID of the project. Example: 1

user   integer   

The ID of the user. Example: 42

Body Parameters

started_at   date   

The start date when this rate becomes effective (YYYY-MM-DD). Example: 2024-01-01

rate   numeric   

The hourly rate. Example: 85.50

Update a bill rate.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/projects/1/users/1/bill-rates/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"started_at\": \"2024-02-01\",
    \"rate\": \"90.00\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/1/users/1/bill-rates/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "started_at": "2024-02-01",
    "rate": "90.00"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 3,
    "project_id": 1,
    "user_id": 42,
    "rate": 90,
    "started_at": "2024-02-01T00:00:00.000000Z",
    "created_at": "2023-12-20T09:45:00.000000Z",
    "updated_at": "2023-12-25T11:20:00.000000Z",
    "status": "future"
}
 

Example response (403, unauthorized):


{
    "message": "This action is unauthorized."
}
 

Example response (404, not_found):


{
    "message": "Bill rate not found for this user"
}
 

Example response (422, duplicate_date):


{
    "message": "The given data was invalid.",
    "errors": {
        "started_at": [
            "The start date already exists for this user."
        ]
    }
}
 

Request      

PUT api/v1/projects/{project_id}/users/{user_id}/bill-rates/{billRate_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

project_id   integer   

The ID of the project. Example: 1

user_id   integer   

The ID of the user. Example: 1

billRate_id   integer   

The ID of the billRate. Example: 1

project   integer   

The ID of the project. Example: 1

user   integer   

The ID of the user. Example: 42

billRate   integer   

The ID of the bill rate. Example: 3

Body Parameters

started_at   date  optional  

The start date when this rate becomes effective (YYYY-MM-DD). Example: 2024-02-01

rate   numeric  optional  

The hourly rate. Example: 90.00

Delete a bill rate.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/projects/1/users/1/bill-rates/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/1/users/1/bill-rates/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (403, unauthorized):


{
    "message": "This action is unauthorized."
}
 

Example response (404, not_found):


{
    "message": "Bill rate not found for this user"
}
 

Example response (422, cannot_delete):


{
    "message": "The given data was invalid.",
    "errors": {
        "error": [
            "Current and past bill rate cannot be deleted"
        ]
    }
}
 

Request      

DELETE api/v1/projects/{project_id}/users/{user_id}/bill-rates/{billRate_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

project_id   integer   

The ID of the project. Example: 1

user_id   integer   

The ID of the user. Example: 1

billRate_id   integer   

The ID of the billRate. Example: 1

project   integer   

The ID of the project. Example: 1

user   integer   

The ID of the user. Example: 42

billRate   integer   

The ID of the bill rate. Example: 3

Boards

APIs for managing project boards.

Boards group tasks inside a project. Use these endpoints to list, create, update, and delete project boards within your team.

Display a paginated list of project boards.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/boards?search=Marketing&project_id=5&per_page=50&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/boards"
);

const params = {
    "search": "Marketing",
    "project_id": "5",
    "per_page": "50",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 10,
            "title": "Marketing pipeline",
            "description": "High level marketing workflow.",
            "project_id": 3,
            "user_id": 14,
            "team_id": 8,
            "created_at": "2025-01-10T12:30:00.000000Z",
            "updated_at": "2025-01-10T12:30:00.000000Z",
            "deleted_at": null
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/boards?page=1",
        "last": "https://example.com/api/v1/boards?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/boards",
        "per_page": 30,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/boards

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Filter boards by partial match in the board title. Example: Marketing

project_id   integer  optional  

Filter boards that belong to the given project id. Example: 5

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, title, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new project board.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/boards" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"title\": \"Marketing pipeline\",
    \"description\": \"High level marketing workflow.\",
    \"project_id\": 3
}"
const url = new URL(
    "https://app.corcava.com/api/v1/boards"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "title": "Marketing pipeline",
    "description": "High level marketing workflow.",
    "project_id": 3
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 10,
    "title": "Marketing pipeline",
    "description": "High level marketing workflow.",
    "project_id": 3,
    "user_id": 14,
    "team_id": 8,
    "created_at": "2025-01-10T12:30:00.000000Z",
    "updated_at": "2025-01-10T12:30:00.000000Z",
    "deleted_at": null
}
 

Example response (422, validation_error):


{
    "message": "Project not found"
}
 

Request      

POST api/v1/boards

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

title   string   

Board title. Example: Marketing pipeline

description   string  optional  

Board description. Example: High level marketing workflow.

project_id   integer  optional  

Project id the board belongs to. Example: 3

user_id   string  optional  
team_id   string  optional  

Display a single board.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/boards/10" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/boards/10"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 10,
    "title": "Marketing pipeline",
    "description": "High level marketing workflow.",
    "project_id": 3,
    "user_id": 14,
    "team_id": 8,
    "created_at": "2025-01-10T12:30:00.000000Z",
    "updated_at": "2025-01-10T12:30:00.000000Z",
    "deleted_at": null
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/boards/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Board id. Example: 10

Update a board.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/boards/10" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"title\": \"Marketing pipeline\",
    \"description\": \"High level marketing workflow.\",
    \"project_id\": 3
}"
const url = new URL(
    "https://app.corcava.com/api/v1/boards/10"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "title": "Marketing pipeline",
    "description": "High level marketing workflow.",
    "project_id": 3
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 10,
    "title": "Marketing pipeline",
    "description": "High level marketing workflow.",
    "project_id": 3,
    "user_id": 14,
    "team_id": 8,
    "created_at": "2025-01-10T12:30:00.000000Z",
    "updated_at": "2025-01-10T16:45:00.000000Z",
    "deleted_at": null
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/boards/{id}

PATCH api/v1/boards/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Board id. Example: 10

Body Parameters

title   string  optional  

Board title. Example: Marketing pipeline

description   string  optional  

Board description. Example: High level marketing workflow.

project_id   integer  optional  

Project id the board belongs to. Example: 3

user_id   string  optional  
team_id   string  optional  

Delete a board.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/boards/10" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/boards/10"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/boards/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Board id. Example: 10

Export board activity with time tracking data.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/boards/10/export-activity?start_date=2025-01-01&end_date=2025-01-31&group_by=member&time_format=hms" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"start_date\": \"2026-09-15T03:18:22\",
    \"end_date\": \"2052-10-08\",
    \"group_by\": \"task\",
    \"time_format\": \"seconds\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/boards/10/export-activity"
);

const params = {
    "start_date": "2025-01-01",
    "end_date": "2025-01-31",
    "group_by": "member",
    "time_format": "hms",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "start_date": "2026-09-15T03:18:22",
    "end_date": "2052-10-08",
    "group_by": "task",
    "time_format": "seconds"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, grouped_by_member_seconds):


{
    "john doe": [
        {
            "task": "Marketing campaign",
            "time": 7200
        },
        {
            "task": "Website redesign",
            "time": 3600
        }
    ],
    "jane smith": [
        {
            "task": "Marketing campaign",
            "time": 5400
        }
    ]
}
 

Example response (200, grouped_by_task_hms):


{
    "Marketing campaign": [
        {
            "member": "john doe",
            "time": "02:00:00"
        },
        {
            "member": "jane smith",
            "time": "01:30:00"
        }
    ],
    "Website redesign": [
        {
            "member": "john doe",
            "time": "01:00:00"
        }
    ]
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Example response (422, validation_error):


{
    "message": "Invalid parameters"
}
 

Request      

GET api/v1/boards/{id}/export-activity

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Board id. Example: 10

Query Parameters

start_date   string   

Start date for the export range (YYYY-MM-DD). Example: 2025-01-01

end_date   string   

End date for the export range (YYYY-MM-DD). Example: 2025-01-31

group_by   string   

Grouping option: 'member' or 'task'. Example: member

time_format   string  optional  

Time format: 'seconds' (integer) or 'hms' (HH:MM:SS string). Defaults to 'seconds'. Example: hms

Body Parameters

start_date   string   

Must be a valid date. Example: 2026-09-15T03:18:22

end_date   string   

Must be a valid date. Must be a date after or equal to start_date. Example: 2052-10-08

group_by   string   

Example: task

Must be one of:
  • member
  • task
time_format   string  optional  

Example: seconds

Must be one of:
  • seconds
  • hms

List columns for a board.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/boards/10/columns" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/boards/10/columns"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "name": "To Do",
            "is_todo": true,
            "is_done": false,
            "project_board_id": 10,
            "team_id": 1,
            "order": 0
        },
        {
            "id": 2,
            "name": "In Progress",
            "is_todo": false,
            "is_done": false,
            "project_board_id": 10,
            "team_id": 1,
            "order": 1
        }
    ]
}
 

Example response (404, not_found):


{
    "message": "Board not found"
}
 

Request      

GET api/v1/boards/{board_id}/columns

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

board_id   integer   

Board id. Example: 10

Create a new column in a board.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/boards/10/columns" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"To Do\",
    \"is_todo\": true,
    \"is_done\": false,
    \"order\": 0
}"
const url = new URL(
    "https://app.corcava.com/api/v1/boards/10/columns"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "To Do",
    "is_todo": true,
    "is_done": false,
    "order": 0
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "data": {
        "id": 5,
        "name": "To Do",
        "is_todo": true,
        "is_done": false,
        "project_board_id": 10,
        "team_id": 1,
        "order": 0
    }
}
 

Example response (404, not_found):


{
    "message": "Board not found"
}
 

Request      

POST api/v1/boards/{board_id}/columns

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

board_id   integer   

Board id. Example: 10

Body Parameters

name   string   

Column name. Example: To Do

is_todo   boolean  optional  

Whether this is the initial/todo column. Example: true

is_done   boolean  optional  

Whether this is the done/completed column. Example: false

order   integer  optional  

Column position (0-based). Example: 0

Update a column.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/boards/10/columns/5" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"In Progress\",
    \"is_todo\": false,
    \"is_done\": false,
    \"order\": 1
}"
const url = new URL(
    "https://app.corcava.com/api/v1/boards/10/columns/5"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "In Progress",
    "is_todo": false,
    "is_done": false,
    "order": 1
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "data": {
        "id": 5,
        "name": "In Progress",
        "is_todo": false,
        "is_done": false,
        "project_board_id": 10,
        "team_id": 1,
        "order": 1
    }
}
 

Example response (404, not_found):


{
    "message": "Column not found"
}
 

Request      

PUT api/v1/boards/{board_id}/columns/{column_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

board_id   integer   

Board id. Example: 10

column_id   integer   

Column id. Example: 5

Body Parameters

name   string  optional  

Column name. Example: In Progress

is_todo   boolean  optional  

Whether this is the initial/todo column. Example: false

is_done   boolean  optional  

Whether this is the done/completed column. Example: false

order   integer  optional  

Column position (0-based). Example: 1

Delete a column.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/boards/10/columns/5" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/boards/10/columns/5"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Column not found"
}
 

Example response (422, has_tasks):


{
    "message": "Cannot delete column with tasks. Move or delete tasks first."
}
 

Request      

DELETE api/v1/boards/{board_id}/columns/{column_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

board_id   integer   

Board id. Example: 10

column_id   integer   

Column id. Example: 5

CRM Emails

One-to-one CRM email drafts and send for contacts (Gmail).

List CRM emails (drafts or sent).

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/emails?status=draft&contact_id=15&per_page=20" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/emails"
);

const params = {
    "status": "draft",
    "contact_id": "15",
    "per_page": "20",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: X-Inertia
access-control-allow-origin: *
set-cookie: XSRF-TOKEN=eyJpdiI6Ill1NmpLRlo4VFo0YXNFRy9GUjlpcnc9PSIsInZhbHVlIjoidTFmd09aWkI3czZYNFI4OWFpZ3VqQWtUcEVUMFo1d1VGR2doOG1oWUd1bjRnUXEvUUZUd245dzFDdUlKY3JOU0dMaFIwVERVamcybTdYaFRrNzRneElYZXZqTzdpMlQyY3RvNUpQSFQ4d2xUQ3RES1lqYnVBOVppMVVzZlZKYUEiLCJtYWMiOiI3MGFmNzhiY2IxMjc0YmI1ZDc0YzhkZGMxYWFhNGUxZjRlZTdjZjQyZmM2OTE2OTdjZTY2N2Y4MTE2MjMzMzZhIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; samesite=lax; corcava_session=eyJpdiI6IkRVaDc0T1JaTk42bnlDOU1YN0dHNEE9PSIsInZhbHVlIjoiSEVUUmFwT3ZwNVduWmdjUGloc1NKcFJCcFc4MjQzdWppYjlSc3Y3d2sva3IzUDRNTGtuYlRpME9SbllhU2NRZFROUHBWZ2h3SXE1M1FLMXc0dW00VGNiNTNtWXc3UXdpYkNORVdiQkFQN0FoSnJDd3BhN3NQZWFVTGI4ZG83SGUiLCJtYWMiOiJmZTBlMjM3OGU0ZGU3MGZmZDA3MGI3MTBkNTM1ODQyYzg5Yzc4YTMwMTk3ZmU5MTIxMmJhMGRjM2IwYWUzMmRlIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; httponly; samesite=lax
 

{
    "message": "Invalid API Key"
}
 

Request      

GET api/v1/emails

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

status   string  optional  

Filter by status: draft, sent, failed, queued. Example: draft

contact_id   integer  optional  

Filter by contact id. Example: 15

per_page   integer  optional  

Results per page (max 50). Example: 20

Show a CRM email.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/emails/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/emails/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: X-Inertia
access-control-allow-origin: *
set-cookie: XSRF-TOKEN=eyJpdiI6ImZYMENsalJDMlduejZjM2xzbzJDdFE9PSIsInZhbHVlIjoidUNaT2JFM2FqVmFWR3kzZE5lR1pSR1A3V3FhYUNxK1E1T0JWWUovZ3lTYS9oTkVkbDNJZXdsWkIrTEkyVnExZjhqQklGZ1FjcTFBNm5nWXVPc3cwR2pLZmpZWTNxRFE3akhkMG44NEtFak5UYUxkNFljSjV2R2pSUjczZzZVd2MiLCJtYWMiOiJlNjM4ODVkNjA2ZjI5YThiY2M5NTYwZGZlZjYzNDBlODJlODIzZTA4MzI5NWU2ODYyMjBmNDM3ODEyY2UyNzg5IiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; samesite=lax; corcava_session=eyJpdiI6IjhBdlgzWnhLdVFubWRiVDNKRjZiM1E9PSIsInZhbHVlIjoiN1N1aDJELzNyNXBwWTFXeitVWkZMMUR3NU5QYnNCWHpkYk5hOXdxQUZ3K241S29oZktrMGlmcVh6MW50UXZqZXVJcDR5dUpMN2FkUUtWNnBpdGpuMHVOS21nRy80Q1ljVnJVL2N5TzdPWmJ2WDUxQVBLZFh5cUZPd3kvQkVmMlEiLCJtYWMiOiIyODdhZjFlZjk1MjQ1YTUwY2ZjNGNkMDc4ODBiNzNkYTVjZDVhOGZiNjY5YTZkNDRkYmE2ZGUxZWIxZTA1YzdkIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; httponly; samesite=lax
 

{
    "message": "Invalid API Key"
}
 

Request      

GET api/v1/emails/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the email. Example: 1

Update a draft email.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/emails/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "to=b"\
    --form "subject=n"\
    --form "body=g"\
    --form "scheduled_at=z"\
    --form "cc[]=m"\
    --form "bcc[]=i"\
    --form "remove_attachment_ids[]=16"\
    --form "attachments[]=@/tmp/phpvmvghduach2n8kfNXIF" 
const url = new URL(
    "https://app.corcava.com/api/v1/emails/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('to', 'b');
body.append('subject', 'n');
body.append('body', 'g');
body.append('scheduled_at', 'z');
body.append('cc[]', 'm');
body.append('bcc[]', 'i');
body.append('remove_attachment_ids[]', '16');
body.append('attachments[]', document.querySelector('input[name="attachments[]"]').files[0]);

fetch(url, {
    method: "PUT",
    headers,
    body,
}).then(response => response.json());

Request      

PUT api/v1/emails/{id}

PATCH api/v1/emails/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the email. Example: 1

Body Parameters

to   string  optional  

Must be a valid email address. Must not be greater than 255 characters. Example: b

subject   string  optional  

Must not be greater than 500 characters. Example: n

body   string  optional  

Must not be greater than 50000 characters. Example: g

scheduled_at   string  optional  

Must not be greater than 64 characters. Example: z

cc   string[]   

Must be a valid email address. Must not be greater than 255 characters.

bcc   string[]   

Must be a valid email address. Must not be greater than 255 characters.

attachments   file[]  optional  

Must be a file. Must not be greater than 25600 kilobytes.

remove_attachment_ids   integer[]  optional  

Cancel (discard) a draft email.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/emails/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/emails/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Request      

DELETE api/v1/emails/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the email. Example: 1

Create a draft email for a contact.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/emails/draft" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "contact_id=15"\
    --form "contact_ref[id]=16"\
    --form "contact_ref[email][email protected]"\
    --form "[email protected]"\
    --form "subject=Following up"\
    --form "body=<p>Hi Alex,</p><p>Thanks for your note.</p>"\
    --form "mailbox_id=3"\
    --form "[email protected]"\
    --form "from=i"\
    --form "scheduled_at=2026-07-29T09:00:00+00:00"\
    --form "cc[]=y"\
    --form "bcc[]=v"\
    --form "reply_to_incoming_email_id=45678"\
    --form "reply_to_outgoing_email_id=12345"\
    --form "remove_attachment_ids[]=16"\
    --form "attachments[]=@/tmp/php8lm9kto7jhtr9C9sXXQ" 
const url = new URL(
    "https://app.corcava.com/api/v1/emails/draft"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('contact_id', '15');
body.append('contact_ref[id]', '16');
body.append('contact_ref[email]', '[email protected]');
body.append('to', '[email protected]');
body.append('subject', 'Following up');
body.append('body', '<p>Hi Alex,</p><p>Thanks for your note.</p>');
body.append('mailbox_id', '3');
body.append('from_mailbox', '[email protected]');
body.append('from', 'i');
body.append('scheduled_at', '2026-07-29T09:00:00+00:00');
body.append('cc[]', 'y');
body.append('bcc[]', 'v');
body.append('reply_to_incoming_email_id', '45678');
body.append('reply_to_outgoing_email_id', '12345');
body.append('remove_attachment_ids[]', '16');
body.append('attachments[]', document.querySelector('input[name="attachments[]"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Request      

POST api/v1/emails/draft

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

Body Parameters

contact_id   integer  optional  

Contact to associate the draft with. This field is required when none of reply_to_incoming_email_id and contact_ref are present. The id of an existing record in the contacts table. Example: 15

contact_ref   object  optional  
id   integer  optional  

Example: 16

email   string  optional  

Must be a valid email address. Must not be greater than 255 characters. Example: [email protected]

to   string  optional  

Recipient email. Defaults to the contact email when omitted. Must be a valid email address. Must not be greater than 255 characters. Example: [email protected]

subject   string  optional  

Email subject line. Must not be greater than 500 characters. Example: Following up

body   string   

HTML message body. Use separate

tags per paragraph; use

    /
      with
    1. for lists (not inline hyphens). Do not wrap the entire email in one

      . Corcava renders HTML as received. Must not be greater than 50000 characters. Example: <p>Hi Alex,</p><p>Thanks for your note.</p>

mailbox_id   integer  optional  

Mailbox id to send from. Uses the default mailbox when omitted. Example: 3

from_mailbox   string  optional  

Send-from mailbox email address (alternative to mailbox_id). Must be a valid email address. Must not be greater than 255 characters. Example: [email protected]

from   string  optional  

Must be a valid email address. Must not be greater than 255 characters. Example: i

scheduled_at   string  optional  

Optional ISO 8601 datetime to schedule the send. Must not be greater than 64 characters. Example: 2026-07-29T09:00:00+00:00

cc   string[]   

Must be a valid email address. Must not be greater than 255 characters.

bcc   string[]   

Must be a valid email address. Must not be greater than 255 characters.

reply_to_incoming_email_id   integer  optional  

Link draft as a reply to this incoming CRM email id. The id of an existing record in the incoming_emails table. Example: 45678

reply_to_outgoing_email_id   integer  optional  

Link draft as a reply to this sent CRM email id. The id of an existing record in the outgoing_emails table. Example: 12345

attachments   file[]  optional  

Must be a file. Must not be greater than 25600 kilobytes.

remove_attachment_ids   integer[]  optional  

AI-generate a reply or new email draft (subject + body). Does not save — use POST /emails/draft to persist.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/emails/generate-draft" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"contact_id\": 15,
    \"instruction\": \"Reply warmly and propose a call next week.\",
    \"thread_key\": \"thread:abc123\",
    \"sender_email\": \"[email protected]\",
    \"reply_to_incoming_email_id\": 45678,
    \"reply_to_outgoing_email_id\": 12345
}"
const url = new URL(
    "https://app.corcava.com/api/v1/emails/generate-draft"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "contact_id": 15,
    "instruction": "Reply warmly and propose a call next week.",
    "thread_key": "thread:abc123",
    "sender_email": "[email protected]",
    "reply_to_incoming_email_id": 45678,
    "reply_to_outgoing_email_id": 12345
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/v1/emails/generate-draft

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

contact_id   integer  optional  

Contact the generated draft is for. This field is required when reply_to_incoming_email_id is not present. The id of an existing record in the contacts table. Example: 15

instruction   string  optional  

Optional guidance for the AI draft (tone, points to cover, etc.). Must not be greater than 2000 characters. Example: Reply warmly and propose a call next week.

thread_key   string  optional  

Inbox thread key from GET /api/v1/inbox when replying in-thread. Must not be greater than 500 characters. Example: thread:abc123

sender_email   string  optional  

Sender email scope from the inbox list (with thread_key). Must not be greater than 255 characters. Example: [email protected]

reply_to_incoming_email_id   integer  optional  

Generate as a reply linked to this incoming email id. The id of an existing record in the incoming_emails table. Example: 45678

reply_to_outgoing_email_id   integer  optional  

Generate as a reply linked to this sent email id. The id of an existing record in the outgoing_emails table. Example: 12345

Schedule a draft email for future send (RFC 3339 with offset required).

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/emails/1/schedule" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"scheduled_at\": \"b\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/emails/1/schedule"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "scheduled_at": "b"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/v1/emails/{email_id}/schedule

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

email_id   integer   

The ID of the email. Example: 1

Body Parameters

scheduled_at   string   

Must match the regex /[Zz]|[+-]\d{2}:?\d{2}$/. Must not be greater than 64 characters. Example: b

Clear schedule on a draft/scheduled email (returns to normal draft).

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/emails/1/unschedule" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/emails/1/unschedule"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/v1/emails/{email_id}/unschedule

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

email_id   integer   

The ID of the email. Example: 1

Send a draft email via the connected Gmail mailbox.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/emails/1/send" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/emails/1/send"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/v1/emails/{email_id}/send

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

email_id   integer   

The ID of the email. Example: 1

CRM Inbox

Read synced Gmail inbox threads for reply drafting via MCP / Public API.

List inbox contact/sender groups with thread previews.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/inbox?search=acme&page=1&per_page=20&view=inbox&inbox_filter=unanswered" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"inbox_filter\": \"unanswered\",
    \"mailbox_ids\": [
        16
    ]
}"
const url = new URL(
    "https://app.corcava.com/api/v1/inbox"
);

const params = {
    "search": "acme",
    "page": "1",
    "per_page": "20",
    "view": "inbox",
    "inbox_filter": "unanswered",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "inbox_filter": "unanswered",
    "mailbox_ids": [
        16
    ]
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: X-Inertia
access-control-allow-origin: *
set-cookie: XSRF-TOKEN=eyJpdiI6ImlIUnNONUhDZytuWHNHREw5YTQrd2c9PSIsInZhbHVlIjoiTlVQOERYVWorVkVvcUJvWDh6OFNORXhOU2wyMU5VV3VaSkNUcGxNaWVyV01vbDg2MGdUTGN1NXRwREMvcVhaU0lqeUNMVWJaY2JwM2N0dTlNdEZLejZUeUhXZ1AxOU41R1BFc2t5WXhQUzV4UFo3cnFWZ2VBMFB0NVZ1b2ZRRHQiLCJtYWMiOiJiNzczYmU0YTBlNzM0NTIyMjE1NTA0ZGY1YjAzNzQyNGViYjVmZTg5NDZhN2U3Nzc2OGE2NTgxNmRkMmIyMmIzIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; samesite=lax; corcava_session=eyJpdiI6InFvMS85UzZnUytBQ1dIMXFMeFRwR1E9PSIsInZhbHVlIjoiWFhKOXdKWTNVQUNFY3k3YmNEQXpsVlNnLzUrb0JFVjJiWkF3SWFmTUhDeUhUcVNWWHNRaGtwUXcxVGo1K0x2SHNsdXVLamRBRVVpQURqdjl4SXBNdkZHb1pXNTlSM2wyUkxGMXUvVCsxQjgvelA4cFZjcVNuNmtPY1Z3TUxBWW0iLCJtYWMiOiJjNTJlNTNiM2I0ZjMzMzU2NWRjNjMzMzAxMmU1NDE3NzZmYzRjMWQ1MjUyNTJiYTkzMGI1M2EzMGY1YTgwYWUxIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; httponly; samesite=lax
 

{
    "message": "Invalid API Key"
}
 

Request      

GET api/v1/inbox

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Filter by sender name, email, subject, or body preview. Example: acme

page   integer  optional  

Page number. Example: 1

per_page   integer  optional  

Results per page (max 50). Example: 20

view   string  optional  

Inbox or archived. Example: inbox

inbox_filter   string  optional  

Inbox filter: all, unread, or unanswered. Example: unanswered

Body Parameters

inbox_filter   string   

Example: unanswered

Must be one of:
  • all
  • unread
  • unanswered
mailbox_ids   integer[]  optional  

Must be at least 1.

Resolve inbox reply context from an incoming message id (human URL: /crm-emails/inbox/reply?incoming=…).

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/inbox/reply?incoming=45678" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"incoming\": 16
}"
const url = new URL(
    "https://app.corcava.com/api/v1/inbox/reply"
);

const params = {
    "incoming": "45678",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "incoming": 16
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: X-Inertia
access-control-allow-origin: *
set-cookie: XSRF-TOKEN=eyJpdiI6IkRxOTFpY1Bsd1ZjK1RuVm5ZVE9wRVE9PSIsInZhbHVlIjoiZWlnTEtPTFZtaitRRTBoaUp0ZTRtWitDTUxKem5XVXRKaHFCYVBWSnZFL2p2YzFHWmhQbGpiQXZJbkxCVWNXT01DTU54NjU3cENqZzA0ZlVoMHN6VDVtd0tFUzZZNnlOYTBiajh4L2JSNGdITE5WNlBzd3gzNjZTaFZoMEtBYzIiLCJtYWMiOiIwOGMwYWM0MTBhMDAyNjI0MTE5YjQ0MjAxZDMyMjAwNzA1ODAxY2I0ZjVkZDY2ZDlkNzBkNmQyOTM3YzI5YmQ2IiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; samesite=lax; corcava_session=eyJpdiI6ImRJbWlacUNYV3hPNW5CUS9MbXhsSEE9PSIsInZhbHVlIjoiM3p2YW05QVRUWVVjUUwzN3NoVEF6RFFQaVFPZkVBNks1NXJhSnhsVmNkdkxYTnNmOWVMUFBGZzkybGJ0MTVEUHlHUWdrd3FDeHZFWUhBeGg4TGRENDBwZ0MvYVdodDVLMGRxRy9BL2ZtWmpuRFVpd2VuVDJkb1ZMSjdwanBDQ3AiLCJtYWMiOiJlOTQ2MWNmZTFjNjIxNGM2OWFiODA4ZTc0ZmI5Yzk3NzVkMDVjNmE1YjBmOTMyZjY4MGUwYzMyY2EwMDBkZmY0IiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; httponly; samesite=lax
 

{
    "message": "Invalid API Key"
}
 

Request      

GET api/v1/inbox/reply

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

incoming   integer   

Incoming email id. Example: 45678

Body Parameters

incoming   integer   

Must be at least 1. Example: 16

Get full thread detail (incoming + sent messages in thread).

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/inbox/threads?thread_key=thread%3Aabc123&from=alex%40example.com&sender_scope=s%3Aalex%40example.com&view=inbox" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"thread_key\": \"b\",
    \"sender_scope\": \"n\",
    \"view\": \"inbox\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/inbox/threads"
);

const params = {
    "thread_key": "thread:abc123",
    "from": "[email protected]",
    "sender_scope": "s:[email protected]",
    "view": "inbox",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "thread_key": "b",
    "sender_scope": "n",
    "view": "inbox"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: X-Inertia
access-control-allow-origin: *
set-cookie: XSRF-TOKEN=eyJpdiI6ImZXS2d5Y0pZdGMrZkQ2MXlQZ0RPVnc9PSIsInZhbHVlIjoiSG51MU9SRkh5WEdzQWNhR1NKd2NIY0JwZkF5Q3p3ZGFqYWc0ZnQ4bUwzOVBTRUFLVTFwenhtdGJiM2ZYSks3cVRUczFZZ21heS9GUFhHR2VvKy9nQUlNYjZNeHRxamh5eHg4NHFoSEdXNEhuZDRqWktrRVBJM2dKTEhsQ2dBelYiLCJtYWMiOiJlYjg0OGM0ZTQwM2MzYTY4ZTUwZjg0Y2FkYTUxY2MxYjYwYWViZjQyZTY5Y2I0YzVjYTg4YjhkYzc2YmE1NzBiIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; samesite=lax; corcava_session=eyJpdiI6InZXMUVYbGRHMWYzTHVkeHdmaFNkOWc9PSIsInZhbHVlIjoiV2JkZTRVTndiMzRjZHhEdWxGekdWY2NZM2s3Wi9CenJUOTV2b2tVRXgxTllOR3oxZXA0VW1aZHVVOEh0VkErb1FPbjc5SWRiRG84M3ZzRFQxN2hsMlViUVdsTFpCWEgxSVNkYVk3aUthckZCN2RvdW9zUGZMV0ZKM0pkK0pWOWEiLCJtYWMiOiIxNzYxZjE3Y2I4YTA2Njc5OGNhNDEzNTM3NWNjYjRkZmI4MjFhOTg3ZWQyNjc1Y2ViZTI0NTgwN2UwZjRmNWI2IiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; httponly; samesite=lax
 

{
    "message": "Invalid API Key"
}
 

Request      

GET api/v1/inbox/threads

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

thread_key   string   

Thread key from list inbox. Example: thread:abc123

from   string  optional  

Sender email (preferred). Example: [email protected]

sender_scope   string  optional  

Legacy sender scope from list inbox. Example: s:[email protected]

view   string  optional  

Inbox or archived. Example: inbox

Body Parameters

thread_key   string   

Must not be greater than 500 characters. Example: b

sender_scope   string  optional  

Must not be greater than 500 characters. Example: n

view   string  optional  

Example: inbox

Must be one of:
  • inbox
  • archived

Clients

APIs for managing clients.

Clients represent organisations you collaborate with. These endpoints let you list, create, update, and delete clients that belong to your team.

Display a paginated list of clients.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/clients?search=ACME&user_id=12&is_stripe=1&is_crypto_payments=&per_page=50&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/clients"
);

const params = {
    "search": "ACME",
    "user_id": "12",
    "is_stripe": "1",
    "is_crypto_payments": "0",
    "per_page": "50",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 4,
            "company_name": "ACME Inc.",
            "contact_name": "Alex Johnson",
            "display_name": "ACME Inc.",
            "currency_id": 1,
            "phone": "+1 202 555 0147",
            "email": "[email protected]",
            "address_1": "123 Main St",
            "address_2": null,
            "zip": "10001",
            "country": "USA",
            "city": "New York",
            "stripe_id": null,
            "is_crypto_payments": false,
            "is_stripe": false,
            "notes": "Key enterprise account.",
            "user_id": 12,
            "team_id": 8,
            "created_at": "2025-01-10T08:00:00.000000Z",
            "updated_at": "2025-01-10T08:00:00.000000Z",
            "deleted_at": null
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/clients?page=1",
        "last": "https://example.com/api/v1/clients?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/clients",
        "per_page": 30,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/clients

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Filter clients by company, contact name, email, or phone. Example: ACME

user_id   integer  optional  

Filter clients by owner id. Example: 12

is_stripe   boolean  optional  

Filter by Stripe integration flag. Example: true

is_crypto_payments   boolean  optional  

Filter by crypto payments flag. Example: false

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, company_name, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new client.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/clients" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"company_name\": \"ACME Inc.\",
    \"contact_name\": \"Alex Johnson\",
    \"currency_id\": 1,
    \"phone\": \"+1 202 555 0147\",
    \"email\": \"[email protected]\",
    \"address_1\": \"123 Main St\",
    \"address_2\": \"Suite 502\",
    \"zip\": \"10001\",
    \"country\": \"USA\",
    \"city\": \"New York\",
    \"stripe_id\": \"cus_abc123\",
    \"is_crypto_payments\": false,
    \"is_stripe\": true,
    \"notes\": \"Key enterprise account.\",
    \"user_id\": 12,
    \"tag_names\": [
        \"n\"
    ],
    \"add_tag_names\": [
        \"g\"
    ],
    \"remove_tag_names\": [
        \"z\"
    ],
    \"create_missing_tags\": false
}"
const url = new URL(
    "https://app.corcava.com/api/v1/clients"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "company_name": "ACME Inc.",
    "contact_name": "Alex Johnson",
    "currency_id": 1,
    "phone": "+1 202 555 0147",
    "email": "[email protected]",
    "address_1": "123 Main St",
    "address_2": "Suite 502",
    "zip": "10001",
    "country": "USA",
    "city": "New York",
    "stripe_id": "cus_abc123",
    "is_crypto_payments": false,
    "is_stripe": true,
    "notes": "Key enterprise account.",
    "user_id": 12,
    "tag_names": [
        "n"
    ],
    "add_tag_names": [
        "g"
    ],
    "remove_tag_names": [
        "z"
    ],
    "create_missing_tags": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 4,
    "company_name": "ACME Inc.",
    "contact_name": "Alex Johnson",
    "display_name": "ACME Inc.",
    "currency_id": 1,
    "phone": "+1 202 555 0147",
    "email": "[email protected]",
    "address_1": "123 Main St",
    "address_2": null,
    "zip": "10001",
    "country": "USA",
    "city": "New York",
    "stripe_id": null,
    "is_crypto_payments": false,
    "is_stripe": false,
    "notes": "Key enterprise account.",
    "user_id": 12,
    "team_id": 8,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z",
    "deleted_at": null
}
 

Request      

POST api/v1/clients

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

company_name   string   

Company name. Example: ACME Inc.

contact_name   string  optional  

Primary contact name. Example: Alex Johnson

currency_id   integer  optional  

Currency id. Defaults to your team's base currency. Example: 1

phone   string  optional  

Phone number. Example: +1 202 555 0147

email   string  optional  

Email address. Example: [email protected]

address_1   string  optional  

Address line 1. Example: 123 Main St

address_2   string  optional  

Address line 2. Example: Suite 502

zip   string  optional  

ZIP or postal code. Example: 10001

country   string  optional  

Country. Example: USA

city   string  optional  

City. Example: New York

stripe_id   string  optional  

Stripe customer id. Example: cus_abc123

is_crypto_payments   boolean  optional  

Enable crypto payments for the client. Example: false

is_stripe   boolean  optional  

Enable Stripe billing for the client. Example: true

notes   string  optional  

Internal notes. Example: Key enterprise account.

user_id   integer  optional  

Owner id for the client. Defaults to the authenticated user. Example: 12

team_id   string  optional  
tag_names   string[]  optional  

Must not be greater than 255 characters.

add_tag_names   string[]  optional  

Must not be greater than 255 characters.

remove_tag_names   string[]  optional  

Must not be greater than 255 characters.

create_missing_tags   boolean  optional  

Example: false

Display a single client.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/clients/4" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/clients/4"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 4,
    "company_name": "ACME Inc.",
    "contact_name": "Alex Johnson",
    "display_name": "ACME Inc.",
    "currency_id": 1,
    "phone": "+1 202 555 0147",
    "email": "[email protected]",
    "address_1": "123 Main St",
    "address_2": null,
    "zip": "10001",
    "country": "USA",
    "city": "New York",
    "stripe_id": null,
    "is_crypto_payments": false,
    "is_stripe": false,
    "notes": "Key enterprise account.",
    "user_id": 12,
    "team_id": 8,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z",
    "deleted_at": null
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/clients/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Client id. Example: 4

Update a client.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/clients/4" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"company_name\": \"ACME Inc.\",
    \"contact_name\": \"Alex Johnson\",
    \"currency_id\": 1,
    \"phone\": \"+1 202 555 0147\",
    \"email\": \"[email protected]\",
    \"address_1\": \"123 Main St\",
    \"address_2\": \"Suite 502\",
    \"zip\": \"10001\",
    \"country\": \"USA\",
    \"city\": \"New York\",
    \"stripe_id\": \"cus_abc123\",
    \"is_crypto_payments\": false,
    \"is_stripe\": true,
    \"notes\": \"Key enterprise account.\",
    \"user_id\": 12,
    \"tag_names\": [
        \"n\"
    ],
    \"add_tag_names\": [
        \"g\"
    ],
    \"remove_tag_names\": [
        \"z\"
    ],
    \"create_missing_tags\": true
}"
const url = new URL(
    "https://app.corcava.com/api/v1/clients/4"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "company_name": "ACME Inc.",
    "contact_name": "Alex Johnson",
    "currency_id": 1,
    "phone": "+1 202 555 0147",
    "email": "[email protected]",
    "address_1": "123 Main St",
    "address_2": "Suite 502",
    "zip": "10001",
    "country": "USA",
    "city": "New York",
    "stripe_id": "cus_abc123",
    "is_crypto_payments": false,
    "is_stripe": true,
    "notes": "Key enterprise account.",
    "user_id": 12,
    "tag_names": [
        "n"
    ],
    "add_tag_names": [
        "g"
    ],
    "remove_tag_names": [
        "z"
    ],
    "create_missing_tags": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 4,
    "company_name": "ACME Inc.",
    "contact_name": "Alex Johnson",
    "display_name": "ACME Inc.",
    "currency_id": 1,
    "phone": "+1 202 555 0147",
    "email": "[email protected]",
    "address_1": "123 Main St",
    "address_2": null,
    "zip": "10001",
    "country": "USA",
    "city": "New York",
    "stripe_id": null,
    "is_crypto_payments": false,
    "is_stripe": false,
    "notes": "Key enterprise account.",
    "user_id": 12,
    "team_id": 8,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T11:30:00.000000Z",
    "deleted_at": null
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/clients/{id}

PATCH api/v1/clients/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Client id. Example: 4

Body Parameters

company_name   string  optional  

Company name. Example: ACME Inc.

contact_name   string  optional  

Primary contact name. Example: Alex Johnson

currency_id   integer  optional  

Currency id. Example: 1

phone   string  optional  

Phone number. Example: +1 202 555 0147

email   string  optional  

Email address. Example: [email protected]

address_1   string  optional  

Address line 1. Example: 123 Main St

address_2   string  optional  

Address line 2. Example: Suite 502

zip   string  optional  

ZIP or postal code. Example: 10001

country   string  optional  

Country. Example: USA

city   string  optional  

City. Example: New York

stripe_id   string  optional  

Stripe customer id. Example: cus_abc123

is_crypto_payments   boolean  optional  

Enable crypto payments for the client. Example: false

is_stripe   boolean  optional  

Enable Stripe billing for the client. Example: true

notes   string  optional  

Internal notes. Example: Key enterprise account.

user_id   integer  optional  

Owner id for the client. Example: 12

team_id   string  optional  
tag_names   string[]  optional  

Must not be greater than 255 characters.

add_tag_names   string[]  optional  

Must not be greater than 255 characters.

remove_tag_names   string[]  optional  

Must not be greater than 255 characters.

create_missing_tags   boolean  optional  

Example: true

Delete a client.

requires authentication

Soft-deletes the client. Linked contacts are detached (client_id set to null), not deleted.

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/clients/4" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/clients/4"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/clients/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Client id. Example: 4

Contact Notes

APIs for managing notes attached to contacts.

These endpoints let you list, create, update, and delete notes for a specific contact.

Display a paginated list of notes for a contact.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/contacts/1/notes?per_page=20" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/1/notes"
);

const params = {
    "per_page": "20",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 7,
            "contact_id": 15,
            "user_id": 12,
            "text": "Meeting scheduled for next Tuesday to discuss project requirements.",
            "created_at": "2025-01-15T10:30:00.000000Z",
            "updated_at": "2025-01-15T10:30:00.000000Z"
        },
        {
            "id": 6,
            "contact_id": 15,
            "user_id": 8,
            "text": "Client requested a callback regarding pricing.",
            "created_at": "2025-01-14T14:20:00.000000Z",
            "updated_at": "2025-01-14T14:20:00.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/contacts/15/notes?page=1",
        "last": "https://example.com/api/v1/contacts/15/notes?page=2",
        "prev": null,
        "next": "https://example.com/api/v1/contacts/15/notes?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 2,
        "path": "https://example.com/api/v1/contacts/15/notes",
        "per_page": 20,
        "to": 20,
        "total": 35
    }
}
 

Request      

GET api/v1/contacts/{contact_id}/notes

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

contact_id   integer   

The ID of the contact. Example: 1

contact   integer   

Contact ID. Example: 15

Query Parameters

per_page   integer  optional  

Number of results per page. Maximum: 100. Default: 30. Example: 20

Create a new note for a contact.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/contacts/1/notes" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"text\": \"Meeting scheduled for next Tuesday to discuss project requirements.\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/1/notes"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "text": "Meeting scheduled for next Tuesday to discuss project requirements."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 7,
    "contact_id": 15,
    "user_id": 12,
    "text": "Meeting scheduled for next Tuesday to discuss project requirements.",
    "created_at": "2025-01-15T10:30:00.000000Z",
    "updated_at": "2025-01-15T10:30:00.000000Z"
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "text": [
            "The text field is required."
        ]
    }
}
 

Request      

POST api/v1/contacts/{contact_id}/notes

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

contact_id   integer   

The ID of the contact. Example: 1

contact   integer   

Contact ID. Example: 15

Body Parameters

text   string   

Note content. Maximum 1000 characters. Example: Meeting scheduled for next Tuesday to discuss project requirements.

Update a contact note.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/contacts/1/notes/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"text\": \"Meeting rescheduled to Wednesday due to client availability.\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/1/notes/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "text": "Meeting rescheduled to Wednesday due to client availability."
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 7,
    "contact_id": 15,
    "user_id": 12,
    "text": "Meeting rescheduled to Wednesday due to client availability.",
    "created_at": "2025-01-15T10:30:00.000000Z",
    "updated_at": "2025-01-16T09:15:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "text": [
            "The text field is required."
        ]
    }
}
 

Request      

PUT api/v1/contacts/{contact_id}/notes/{note_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

contact_id   integer   

The ID of the contact. Example: 1

note_id   integer   

The ID of the note. Example: 1

contact   integer   

Contact ID. Example: 15

note   integer   

Note ID. Example: 7

Body Parameters

text   string   

Updated note content. Maximum 1000 characters. Example: Meeting rescheduled to Wednesday due to client availability.

Delete contact note.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/contacts/1/notes/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/1/notes/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/contacts/{contact_id}/notes/{note_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

contact_id   integer   

The ID of the contact. Example: 1

note_id   integer   

The ID of the note. Example: 1

contact   integer   

Contact ID. Example: 15

note   integer   

Note ID. Example: 7

Contact Tasks

APIs for managing tasks related to a contact.

These endpoints allow you to list, create, update, and delete tasks that are associated with a specific contact.

Display a paginated list of contact tasks.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/contacts/1/tasks?per_page=30" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/1/tasks"
);

const params = {
    "per_page": "30",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 3,
            "contact_id": 15,
            "user_id": 7,
            "due_at": "2025-02-01T12:00:00.000000Z",
            "created_at": "2025-01-10T08:00:00.000000Z",
            "updated_at": "2025-01-10T08:00:00.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/contacts/15/tasks?page=1",
        "last": "https://example.com/api/v1/contacts/15/tasks?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/contacts/15/tasks",
        "per_page": 30,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/contacts/{contact_id}/tasks

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

contact_id   integer   

The ID of the contact. Example: 1

contact   integer   

Contact id. Example: 15

Query Parameters

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 30

Create a new task for a contact.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/contacts/1/tasks" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"b\",
    \"description\": \"Eius et animi quos velit et.\",
    \"status\": \"v\",
    \"due_at\": \"2025-02-01T12:00:00Z\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/1/tasks"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "b",
    "description": "Eius et animi quos velit et.",
    "status": "v",
    "due_at": "2025-02-01T12:00:00Z"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 3,
    "contact_id": 15,
    "user_id": 7,
    "due_at": "2025-02-01T12:00:00.000000Z",
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z"
}
 

Request      

POST api/v1/contacts/{contact_id}/tasks

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

contact_id   integer   

The ID of the contact. Example: 1

contact   integer   

Contact id. Example: 15

Body Parameters

name   string   

Must not be greater than 255 characters. Example: b

description   string  optional  

Example: Eius et animi quos velit et.

status   string   

Must not be greater than 50 characters. Example: v

due_at   string   

Due date and time (ISO 8601). Example: 2025-02-01T12:00:00Z

Update a contact task.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/contacts/1/tasks/8" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"b\",
    \"description\": \"Eius et animi quos velit et.\",
    \"status\": \"v\",
    \"due_at\": \"2025-02-05T09:00:00Z\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/1/tasks/8"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "b",
    "description": "Eius et animi quos velit et.",
    "status": "v",
    "due_at": "2025-02-05T09:00:00Z"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 3,
    "contact_id": 15,
    "user_id": 7,
    "due_at": "2025-02-05T09:00:00.000000Z",
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-11T10:30:00.000000Z"
}
 

Request      

PUT api/v1/contacts/{contact_id}/tasks/{task_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

contact_id   integer   

The ID of the contact. Example: 1

task_id   integer   

The ID of the task. Example: 8

contact   integer   

Contact id. Example: 15

task   integer   

Task id. Example: 3

Body Parameters

name   string   

Must not be greater than 255 characters. Example: b

description   string  optional  

Example: Eius et animi quos velit et.

status   string   

Must not be greater than 50 characters. Example: v

due_at   string   

New due date and time (ISO 8601). Example: 2025-02-05T09:00:00Z

Delete a contact task.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/contacts/1/tasks/8" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/1/tasks/8"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Request      

DELETE api/v1/contacts/{contact_id}/tasks/{task_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

contact_id   integer   

The ID of the contact. Example: 1

task_id   integer   

The ID of the task. Example: 8

contact   integer   

Contact id. Example: 15

task   integer   

Task id. Example: 3

Contacts

APIs for managing contacts.

Contacts represent people related to your clients. Use these endpoints to list, create, update, and delete contacts within your team.

Display a paginated list of contacts.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/contacts?search=John+Doe&client_id=4&user_id=12&per_page=50&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts"
);

const params = {
    "search": "John Doe",
    "client_id": "4",
    "user_id": "12",
    "per_page": "50",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 21,
            "client_id": 4,
            "first_name": "Alex",
            "last_name": "Johnson",
            "display_name": "Alex Johnson",
            "company_name": "ACME Inc.",
            "website": "https://acme.inc",
            "email": "[email protected]",
            "phone": "+1 202 555 0147",
            "user_id": 12,
            "team_id": 8,
            "skype": null,
            "telegram": "@alex",
            "linkedin": "https://linkedin.com/in/alex",
            "birth_date": "1992-09-15",
            "last_contacted_at": "2025-01-10T15:00:00.000000Z",
            "address_line_1": "123 Main St",
            "city": "New York",
            "zip": "10001",
            "country": "USA",
            "description": "Primary decision maker",
            "goal": "Close enterprise deal by Q3",
            "outreach_id": null,
            "company_id": null,
            "custom_fields": {
                "extra emails": "[email protected], [email protected]",
                "foo-bar": "[email protected]"
            },
            "created_at": "2025-01-10T08:00:00.000000Z",
            "updated_at": "2025-01-10T15:00:00.000000Z",
            "deleted_at": null
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/contacts?page=1",
        "last": "https://example.com/api/v1/contacts?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/contacts",
        "per_page": 50,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/contacts

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Filter contacts by name (including full name), email, phone, or company. Example: John Doe

client_id   integer  optional  

Filter contacts by client id. Example: 4

user_id   integer  optional  

Filter contacts by owner id. Example: 12

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, first_name, last_name, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new contact.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/contacts" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"first_name\": \"Alex\",
    \"last_name\": \"Johnson\",
    \"company_name\": \"ACME Inc.\",
    \"website\": \"https:\\/\\/acme.inc\",
    \"client_id\": 4,
    \"email\": \"[email protected]\",
    \"phone\": \"+1 202 555 0147\",
    \"user_id\": 12,
    \"skype\": \"j\",
    \"telegram\": \"@alex\",
    \"linkedin\": \"https:\\/\\/linkedin.com\\/in\\/alex\",
    \"birth_date\": \"2026-09-15T03:18:22\",
    \"last_contacted_at\": \"2026-09-15T03:18:22\",
    \"address_line_1\": \"k\",
    \"city\": \"h\",
    \"zip\": \"w\",
    \"country\": \"a\",
    \"description\": \"Primary decision maker\",
    \"goal\": \"Close enterprise deal by Q3\",
    \"outreach_id\": 16,
    \"company_id\": 16,
    \"custom_fields\": {
        \"extra emails\": \"[email protected], [email protected]\",
        \"foo-bar\": \"[email protected]\"
    },
    \"client_ref\": {
        \"id\": 16,
        \"name\": \"n\"
    },
    \"tag_names\": [
        \"g\"
    ],
    \"add_tag_names\": [
        \"z\"
    ],
    \"remove_tag_names\": [
        \"m\"
    ],
    \"create_missing_tags\": true
}"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "first_name": "Alex",
    "last_name": "Johnson",
    "company_name": "ACME Inc.",
    "website": "https:\/\/acme.inc",
    "client_id": 4,
    "email": "[email protected]",
    "phone": "+1 202 555 0147",
    "user_id": 12,
    "skype": "j",
    "telegram": "@alex",
    "linkedin": "https:\/\/linkedin.com\/in\/alex",
    "birth_date": "2026-09-15T03:18:22",
    "last_contacted_at": "2026-09-15T03:18:22",
    "address_line_1": "k",
    "city": "h",
    "zip": "w",
    "country": "a",
    "description": "Primary decision maker",
    "goal": "Close enterprise deal by Q3",
    "outreach_id": 16,
    "company_id": 16,
    "custom_fields": {
        "extra emails": "[email protected], [email protected]",
        "foo-bar": "[email protected]"
    },
    "client_ref": {
        "id": 16,
        "name": "n"
    },
    "tag_names": [
        "g"
    ],
    "add_tag_names": [
        "z"
    ],
    "remove_tag_names": [
        "m"
    ],
    "create_missing_tags": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 21,
    "client_id": 4,
    "first_name": "Alex",
    "last_name": "Johnson",
    "display_name": "Alex Johnson",
    "company_name": "ACME Inc.",
    "website": "https://acme.inc",
    "email": "[email protected]",
    "phone": "+1 202 555 0147",
    "user_id": 12,
    "team_id": 8,
    "skype": null,
    "telegram": "@alex",
    "linkedin": "https://linkedin.com/in/alex",
    "birth_date": "1992-09-15",
    "last_contacted_at": null,
    "address_line_1": "123 Main St",
    "city": "New York",
    "zip": "10001",
    "country": "USA",
    "description": "Primary decision maker",
    "goal": "Close enterprise deal by Q3",
    "outreach_id": null,
    "company_id": null,
    "custom_fields": {
        "extra emails": "[email protected], [email protected]",
        "foo-bar": "[email protected]"
    },
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z",
    "deleted_at": null
}
 

Example response (422, validation_error):


{
    "message": "Client not found"
}
 

Request      

POST api/v1/contacts

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

first_name   string   

Contact first name. Example: Alex

last_name   string  optional  

Contact last name. Example: Johnson

company_name   string  optional  

Company name. Example: ACME Inc.

website   string  optional  

Company website. Example: https://acme.inc

client_id   integer  optional  

Client id the contact belongs to. Example: 4

email   string  optional  

Contact email address. Example: [email protected]

phone   string  optional  

Contact phone number. Example: +1 202 555 0147

user_id   integer  optional  

Owner id for the contact. Defaults to the authenticated user. Example: 12

team_id   string  optional  
skype   string  optional  

Must not be greater than 255 characters. Example: j

telegram   string  optional  

Telegram handle. Example: @alex

linkedin   string  optional  

LinkedIn profile URL. Example: https://linkedin.com/in/alex

birth_date   string  optional  

Must be a valid date. Example: 2026-09-15T03:18:22

last_contacted_at   string  optional  

Must be a valid date. Example: 2026-09-15T03:18:22

address_line_1   string  optional  

Must not be greater than 255 characters. Example: k

city   string  optional  

Must not be greater than 255 characters. Example: h

zip   string  optional  

Must not be greater than 255 characters. Example: w

country   string  optional  

Must not be greater than 255 characters. Example: a

description   string  optional  

Internal contact description. Example: Primary decision maker

goal   string  optional  

Optional outreach goal for this contact (max 5000 characters). Used by AI when drafting emails. Example: Close enterprise deal by Q3

outreach_id   integer  optional  

Example: 16

company_id   integer  optional  

Example: 16

custom_fields   object  optional  

Map of Contact custom field name to string value. Names must match team definitions (case-insensitive).

client_ref   object  optional  
id   integer  optional  

Example: 16

name   string  optional  

Must not be greater than 255 characters. Example: n

tag_names   string[]  optional  

Must not be greater than 255 characters.

add_tag_names   string[]  optional  

Must not be greater than 255 characters.

remove_tag_names   string[]  optional  

Must not be greater than 255 characters.

create_missing_tags   boolean  optional  

Example: true

Display a single contact.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/contacts/21" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/21"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 21,
    "client_id": 4,
    "first_name": "Alex",
    "last_name": "Johnson",
    "display_name": "Alex Johnson",
    "company_name": "ACME Inc.",
    "website": "https://acme.inc",
    "email": "[email protected]",
    "phone": "+1 202 555 0147",
    "user_id": 12,
    "team_id": 8,
    "skype": null,
    "telegram": "@alex",
    "linkedin": "https://linkedin.com/in/alex",
    "birth_date": "1992-09-15",
    "last_contacted_at": "2025-01-10T15:00:00.000000Z",
    "address_line_1": "123 Main St",
    "city": "New York",
    "zip": "10001",
    "country": "USA",
    "description": "Primary decision maker",
    "goal": "Close enterprise deal by Q3",
    "outreach_id": null,
    "company_id": null,
    "custom_fields": {
        "extra emails": "[email protected], [email protected]",
        "foo-bar": "[email protected]"
    },
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T15:00:00.000000Z",
    "deleted_at": null
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/contacts/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Contact id. Example: 21

Update a contact.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/contacts/21" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"first_name\": \"Alex\",
    \"last_name\": \"Johnson\",
    \"company_name\": \"g\",
    \"website\": \"z\",
    \"client_id\": 4,
    \"email\": \"[email protected]\",
    \"phone\": \"+1 202 555 0147\",
    \"user_id\": 12,
    \"skype\": \"j\",
    \"telegram\": \"n\",
    \"linkedin\": \"i\",
    \"birth_date\": \"2026-09-15T03:18:22\",
    \"last_contacted_at\": \"2026-09-15T03:18:22\",
    \"address_line_1\": \"k\",
    \"city\": \"h\",
    \"zip\": \"w\",
    \"country\": \"a\",
    \"description\": \"Primary decision maker\",
    \"goal\": \"Close enterprise deal by Q3\",
    \"outreach_id\": 16,
    \"company_id\": 16,
    \"custom_fields\": {
        \"extra emails\": \"[email protected], [email protected]\"
    },
    \"client_ref\": {
        \"id\": 16,
        \"name\": \"n\"
    },
    \"tag_names\": [
        \"g\"
    ],
    \"add_tag_names\": [
        \"z\"
    ],
    \"remove_tag_names\": [
        \"m\"
    ],
    \"create_missing_tags\": true
}"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/21"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "first_name": "Alex",
    "last_name": "Johnson",
    "company_name": "g",
    "website": "z",
    "client_id": 4,
    "email": "[email protected]",
    "phone": "+1 202 555 0147",
    "user_id": 12,
    "skype": "j",
    "telegram": "n",
    "linkedin": "i",
    "birth_date": "2026-09-15T03:18:22",
    "last_contacted_at": "2026-09-15T03:18:22",
    "address_line_1": "k",
    "city": "h",
    "zip": "w",
    "country": "a",
    "description": "Primary decision maker",
    "goal": "Close enterprise deal by Q3",
    "outreach_id": 16,
    "company_id": 16,
    "custom_fields": {
        "extra emails": "[email protected], [email protected]"
    },
    "client_ref": {
        "id": 16,
        "name": "n"
    },
    "tag_names": [
        "g"
    ],
    "add_tag_names": [
        "z"
    ],
    "remove_tag_names": [
        "m"
    ],
    "create_missing_tags": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 21,
    "client_id": 4,
    "first_name": "Alex",
    "last_name": "Johnson",
    "display_name": "Alex Johnson",
    "company_name": "ACME Inc.",
    "website": "https://acme.inc",
    "email": "[email protected]",
    "phone": "+1 202 555 0147",
    "user_id": 12,
    "team_id": 8,
    "skype": null,
    "telegram": "@alex",
    "linkedin": "https://linkedin.com/in/alex",
    "birth_date": "1992-09-15",
    "last_contacted_at": "2025-01-10T15:00:00.000000Z",
    "address_line_1": "123 Main St",
    "city": "New York",
    "zip": "10001",
    "country": "USA",
    "description": "Primary decision maker",
    "goal": "Close enterprise deal by Q3",
    "outreach_id": null,
    "company_id": null,
    "custom_fields": {
        "extra emails": "[email protected], [email protected]",
        "foo-bar": "[email protected]"
    },
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T18:30:00.000000Z",
    "deleted_at": null
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/contacts/{id}

PATCH api/v1/contacts/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Contact id. Example: 21

Body Parameters

first_name   string  optional  

Contact first name. Example: Alex

last_name   string  optional  

Contact last name. Example: Johnson

company_name   string  optional  

Must not be greater than 255 characters. Example: g

website   string  optional  

Must be a valid URL. Must not be greater than 255 characters. Example: z

client_id   integer  optional  

Client id the contact belongs to. Example: 4

email   string  optional  

Contact email address. Example: [email protected]

phone   string  optional  

Contact phone number. Example: +1 202 555 0147

user_id   integer  optional  

Owner id for the contact. Example: 12

team_id   string  optional  
skype   string  optional  

Must not be greater than 255 characters. Example: j

telegram   string  optional  

Must not be greater than 255 characters. Example: n

linkedin   string  optional  

Must not be greater than 255 characters. Example: i

birth_date   string  optional  

Must be a valid date. Example: 2026-09-15T03:18:22

last_contacted_at   string  optional  

Must be a valid date. Example: 2026-09-15T03:18:22

address_line_1   string  optional  

Must not be greater than 255 characters. Example: k

city   string  optional  

Must not be greater than 255 characters. Example: h

zip   string  optional  

Must not be greater than 255 characters. Example: w

country   string  optional  

Must not be greater than 255 characters. Example: a

description   string  optional  

Internal contact description. Example: Primary decision maker

goal   string  optional  

Optional outreach goal for this contact (max 5000 characters). Used by AI when drafting emails. Example: Close enterprise deal by Q3

outreach_id   integer  optional  

Example: 16

company_id   integer  optional  

Example: 16

custom_fields   object  optional  

Map of Contact custom field name to string value. Names must match team definitions (case-insensitive).

client_ref   object  optional  
id   integer  optional  

Example: 16

name   string  optional  

Must not be greater than 255 characters. Example: n

tag_names   string[]  optional  

Must not be greater than 255 characters.

add_tag_names   string[]  optional  

Must not be greater than 255 characters.

remove_tag_names   string[]  optional  

Must not be greater than 255 characters.

create_missing_tags   boolean  optional  

Example: true

Delete a contact.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/contacts/21" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/contacts/21"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/contacts/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Contact id. Example: 21

Custom Fields

APIs for managing custom field definitions.

Custom fields allow teams to define additional structured data that can be attached to various entities across the system.

Display a paginated list of custom fields.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/custom-fields?per_page=50&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/custom-fields"
);

const params = {
    "per_page": "50",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "name": "priority",
            "label": "Priority",
            "team_id": 8,
            "created_at": "2025-01-10T08:00:00.000000Z",
            "updated_at": "2025-01-10T08:00:00.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/custom-fields?page=1",
        "last": "https://example.com/api/v1/custom-fields?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/custom-fields",
        "per_page": 30,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/custom-fields

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new custom field.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/custom-fields" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"priority\",
    \"type\": \"string\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/custom-fields"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "priority",
    "type": "string"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 1,
    "name": "priority",
    "label": "Priority",
    "team_id": 8,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z"
}
 

Request      

POST api/v1/custom-fields

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

Internal field name. Example: priority

type   string   

Field type. Example: string

Update a custom field.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/custom-fields/3" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"priority\",
    \"type\": \"string\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/custom-fields/3"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "priority",
    "type": "string"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 1,
    "name": "priority",
    "label": "Priority",
    "team_id": 8,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-11T10:30:00.000000Z"
}
 

Request      

PUT api/v1/custom-fields/{field_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

field_id   integer   

The ID of the field. Example: 3

field   integer   

Custom field id. Example: 1

Body Parameters

name   string  optional  

Internal field name. Example: priority

type   string  optional  

Field type. Example: string

Delete a custom field.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/custom-fields/3" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/custom-fields/3"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Request      

DELETE api/v1/custom-fields/{customField_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

customField_id   integer   

The ID of the customField. Example: 3

customField   integer   

Custom field id. Example: 1

Deal Flow Columns

APIs for managing deal pipeline columns/stages.

Deal flow columns represent stages in a sales or deal pipeline. These endpoints let you list, create, update, reorder, and delete columns that belong to your team.

Display a paginated list of deal flow columns.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/deal-columns?name=Proposal&sort=order&direction=asc&per_page=50" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/deal-columns"
);

const params = {
    "name": "Proposal",
    "sort": "order",
    "direction": "asc",
    "per_page": "50",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "name": "Qualified Lead",
            "board_id": 5,
            "team_id": 8,
            "deal_probability": "30%",
            "order": 0,
            "created_at": "2025-01-10T08:00:00.000000Z",
            "updated_at": "2025-01-10T08:00:00.000000Z",
            "deleted_at": null
        },
        {
            "id": 2,
            "name": "Proposal Made",
            "board_id": 5,
            "team_id": 8,
            "deal_probability": "50%",
            "order": 1,
            "created_at": "2025-01-10T08:00:00.000000Z",
            "updated_at": "2025-01-10T08:00:00.000000Z",
            "deleted_at": null
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/deal-columns?page=1",
        "last": "https://example.com/api/v1/deal-columns?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/deal-columns",
        "per_page": 30,
        "to": 2,
        "total": 2
    }
}
 

Request      

GET api/v1/deal-columns

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

name   string  optional  

Filter columns by name. Example: Proposal

sort   string  optional  

Column used for sorting. Allowed: id, name, order, created_at, updated_at. Example: order

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: asc

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

Create a new deal flow column.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/deal-columns" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Proposal Made\",
    \"board_id\": 5,
    \"deal_probability\": \"50%\",
    \"order\": 2
}"
const url = new URL(
    "https://app.corcava.com/api/v1/deal-columns"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Proposal Made",
    "board_id": 5,
    "deal_probability": "50%",
    "order": 2
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "data": {
        "id": 3,
        "name": "Proposal Made",
        "board_id": 5,
        "team_id": 8,
        "deal_probability": "50%",
        "order": 2,
        "created_at": "2025-01-10T10:00:00.000000Z",
        "updated_at": "2025-01-10T10:00:00.000000Z",
        "deleted_at": null
    },
    "message": "Column created successfully"
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "name": [
            "The name field is required."
        ],
        "board_id": [
            "The selected board id is invalid."
        ]
    }
}
 

Request      

POST api/v1/deal-columns

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

Column name. Example: Proposal Made

board_id   integer  optional  

ID of the board this column belongs to. Example: 5

deal_probability   string  optional  

Probability percentage for deals in this stage. Example: 50%

order   integer  optional  

Position in the pipeline (0-based). If not provided, will be added to the end. Example: 2

Update a deal flow column.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/deal-columns/3" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Proposal Submitted\",
    \"board_id\": 5,
    \"deal_probability\": \"60%\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/deal-columns/3"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Proposal Submitted",
    "board_id": 5,
    "deal_probability": "60%"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "data": {
        "id": 3,
        "name": "Proposal Submitted",
        "board_id": 5,
        "team_id": 8,
        "deal_probability": "60%",
        "order": 3,
        "created_at": "2025-01-10T10:00:00.000000Z",
        "updated_at": "2025-01-10T11:30:00.000000Z",
        "deleted_at": null
    },
    "message": "Column updated successfully"
}
 

Example response (404, not_found):


{
    "message": "Column not found"
}
 

Request      

PUT api/v1/deal-columns/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Column ID. Example: 3

Body Parameters

name   string  optional  

Column name. Example: Proposal Submitted

board_id   integer  optional  

ID of the board this column belongs to. Example: 5

deal_probability   string  optional  

Probability percentage for deals in this stage. Example: 60%

Delete a deal flow column.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/deal-columns/3" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/deal-columns/3"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "message": "Column deleted successfully"
}
 

Example response (404, not_found):


{
    "message": "Column not found"
}
 

Request      

DELETE api/v1/deal-columns/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Column ID. Example: 3

Reorder a deal flow column.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/deal-columns/3/order" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"order\": 1
}"
const url = new URL(
    "https://app.corcava.com/api/v1/deal-columns/3/order"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "order": 1
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "data": {
        "id": 3,
        "name": "Proposal Made",
        "board_id": 5,
        "team_id": 8,
        "deal_probability": "50%",
        "order": 1,
        "created_at": "2025-01-10T10:00:00.000000Z",
        "updated_at": "2025-01-10T12:00:00.000000Z",
        "deleted_at": null
    },
    "message": "Column order updated successfully"
}
 

Example response (404, not_found):


{
    "message": "Column not found"
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "order": [
            "The order field is required."
        ]
    }
}
 

Request      

PUT api/v1/deal-columns/{id}/order

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Column ID. Example: 3

Body Parameters

order   integer   

New position in the pipeline (0-based). Example: 1

Deals Management

APIs for managing deals

This controller provides endpoints to create, read, update, delete, and manage the order of deals within the system.

Display a paginated listing of deals.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/deals?search=b&user_id=16&column_id=16&contact_id=16&date_from=2026-09-15T03%3A18%3A22&date_to=2026-09-15T03%3A18%3A22&sort=name&direction=desc&per_page=22" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/deals"
);

const params = {
    "search": "b",
    "user_id": "16",
    "column_id": "16",
    "contact_id": "16",
    "date_from": "2026-09-15T03:18:22",
    "date_to": "2026-09-15T03:18:22",
    "sort": "name",
    "direction": "desc",
    "per_page": "22",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "name": "Big Deal",
            "slug": "big-deal",
            "outreach_id": 3,
            "company_id": 7,
            "contact_id": 15,
            "user_id": 5,
            "team_id": 2,
            "description": "This is a very important deal.",
            "column_id": 4,
            "closed_at": "2024-05-01T00:00:00.000000Z",
            "amount": "10000.00",
            "order": 1,
            "created_at": "2024-04-01T12:00:00.000000Z",
            "updated_at": "2024-04-15T15:30:00.000000Z",
            "deleted_at": null
        }
    ],
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "per_page": 30,
        "to": 30,
        "total": 75
    }
}
 

Example response (401, unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (403, forbidden):


{
    "message": "This action is unauthorized."
}
 

Request      

GET api/v1/deals

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Must not be greater than 500 characters. Example: b

user_id   integer  optional  

Example: 16

column_id   integer  optional  

Example: 16

contact_id   integer  optional  

Example: 16

date_from   string  optional  

Must be a valid date. Example: 2026-09-15T03:18:22

date_to   string  optional  

Must be a valid date. Example: 2026-09-15T03:18:22

sort   string  optional  

Example: name

Must be one of:
  • id
  • name
  • amount
  • created_at
  • updated_at
direction   string  optional  

Example: desc

Must be one of:
  • asc
  • desc
per_page   integer  optional  

Must be at least 1. Must not be greater than 100. Example: 22

Display the specified deal.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/deals/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/deals/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 1,
    "name": "Big Deal",
    "slug": "big-deal",
    "outreach_id": 3,
    "company_id": 7,
    "contact_id": 15,
    "user_id": 5,
    "team_id": 2,
    "description": "This is a very important deal.",
    "column_id": 4,
    "closed_at": "2024-05-01T00:00:00.000000Z",
    "amount": "10000.00",
    "order": 1,
    "created_at": "2024-04-01T12:00:00.000000Z",
    "updated_at": "2024-04-15T15:30:00.000000Z",
    "deleted_at": null
}
 

Example response (401, unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (403, forbidden):


{"message": "This action is unauthorized
 

Example response (404, not_found):


{
    "message": "Deal not found."
}
 

Request      

GET api/v1/deals/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the deal. Example: 1

Store a newly created deal in storage.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/deals" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"\\\"New Deal\\\"\",
    \"description\": \"\\\"This deal is very promising.\\\"\",
    \"closed_at\": \"\\\"2024-06-30\\\"\",
    \"outreach_id\": 3,
    \"contact_id\": 15,
    \"company_id\": 7,
    \"amount\": \"\\\"5000.00\\\"\",
    \"column_id\": 4,
    \"user_id\": 5,
    \"attachments\": [
        \"architecto\"
    ]
}"
const url = new URL(
    "https://app.corcava.com/api/v1/deals"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "\"New Deal\"",
    "description": "\"This deal is very promising.\"",
    "closed_at": "\"2024-06-30\"",
    "outreach_id": 3,
    "contact_id": 15,
    "company_id": 7,
    "amount": "\"5000.00\"",
    "column_id": 4,
    "user_id": 5,
    "attachments": [
        "architecto"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, created):


{
    "id": 2,
    "name": "New Deal",
    "slug": "new-deal",
    "outreach_id": 3,
    "company_id": 7,
    "contact_id": 15,
    "user_id": 5,
    "team_id": 2,
    "description": "This deal is very promising.",
    "column_id": 4,
    "closed_at": "2024-06-30T00:00:00.000000Z",
    "amount": "5000.00",
    "order": 2,
    "created_at": "2024-05-01T10:00:00.000000Z",
    "updated_at": "2024-05-01T10:00:00.000000Z",
    "deleted_at": null
}
 

Example response (400, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "name": [
            "The name field is required."
        ]
    }
}
 

Example response (401, unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (403, forbidden):


{
    "message": "This action is unauthorized."
}
 

Request      

POST api/v1/deals

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

The name of the deal. Example: "New Deal"

description   string  optional  

The description of the deal. Example: "This deal is very promising."

closed_at   date  optional  

The closing date of the deal. Format: YYYY-MM-DD. Example: "2024-06-30"

outreach_id   integer  optional  

The ID of the associated outreach. Example: 3

contact_id   integer  optional  

The ID of the associated contact. Example: 15

company_id   integer  optional  

The ID of the associated company. Example: 7

amount   decimal  optional  

The monetary amount of the deal. Example: "5000.00"

column_id   integer   

The ID of the deal flow column. Example: 4

user_id   integer  optional  

The ID of the user assigned to the deal. Example: 5

attachments   string[]  optional  

An array of files to attach to the deal.

*   file  optional  

Individual attachment files. Example: /tmp/phphnna6r2fuvi7cWmpDpe

Update the specified deal in storage.

requires authentication

To change column or position, use PUT deals/{id}/order (column_id is not accepted here).

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/deals/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"\\\"Updated Deal Name\\\"\",
    \"description\": \"\\\"Updated description.\\\"\",
    \"closed_at\": \"\\\"2024-07-15\\\"\",
    \"outreach_id\": 4,
    \"contact_id\": 16,
    \"company_id\": 8,
    \"amount\": \"\\\"7500.00\\\"\",
    \"user_id\": 6,
    \"attachments\": [
        \"architecto\"
    ]
}"
const url = new URL(
    "https://app.corcava.com/api/v1/deals/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "\"Updated Deal Name\"",
    "description": "\"Updated description.\"",
    "closed_at": "\"2024-07-15\"",
    "outreach_id": 4,
    "contact_id": 16,
    "company_id": 8,
    "amount": "\"7500.00\"",
    "user_id": 6,
    "attachments": [
        "architecto"
    ]
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 1,
    "name": "Updated Deal Name",
    "slug": "updated-deal-name",
    "outreach_id": 4,
    "company_id": 8,
    "contact_id": 16,
    "user_id": 6,
    "team_id": 2,
    "description": "Updated description.",
    "column_id": 5,
    "closed_at": "2024-07-15T00:00:00.000000Z",
    "amount": "7500.00",
    "order": 1,
    "created_at": "2024-04-01T12:00:00.000000Z",
    "updated_at": "2024-05-10T14:20:00.000000Z",
    "deleted_at": null
}
 

Example response (400, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "name": [
            "The name field must not be greater than 255 characters."
        ]
    }
}
 

Example response (401, unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (403, forbidden):


{
    "message": "This action is unauthorized."
}
 

Example response (404, not_found):


{
    "message": "Deal not found."
}
 

Request      

PUT api/v1/deals/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the deal. Example: 1

Body Parameters

name   string  optional  

The name of the deal. Example: "Updated Deal Name"

description   string  optional  

The description of the deal. Example: "Updated description."

closed_at   date  optional  

The closing date of the deal. Format: YYYY-MM-DD. Example: "2024-07-15"

outreach_id   integer  optional  

The ID of the associated outreach. Example: 4

contact_id   integer  optional  

The ID of the associated contact. Example: 16

company_id   integer  optional  

The ID of the associated company. Example: 8

amount   decimal  optional  

The monetary amount of the deal. Example: "7500.00"

user_id   integer  optional  

The ID of the user assigned to the deal. Example: 6

attachments   string[]  optional  

An array of files to attach to the deal.

*   file  optional  

Individual attachment files. Example: /tmp/phpacqbvn16bh3c5gbC0C2

Remove the specified deal from storage.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/deals/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/deals/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "message": "Deal deleted successfully."
}
 

Example response (401, unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (403, forbidden):


{
    "message": "This action is unauthorized."
}
 

Example response (404, not_found):


{
    "message": "Deal not found."
}
 

Request      

DELETE api/v1/deals/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the deal. Example: 1

Update the order of the specified deal.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/deals/order" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"order\": 3,
    \"column_id\": 2
}"
const url = new URL(
    "https://app.corcava.com/api/v1/deals/order"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "order": 3,
    "column_id": 2
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{"data": { ...deal data... }, "message": "Deal order updated successfully."}
 

Example response (400, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "order": [
            "The order field is required."
        ]
    }
}
 

Example response (401, unauthenticated):


{
    "message": "Unauthenticated."
}
 

Example response (403, forbidden):


{
    "message": "This action is unauthorized."
}
 

Example response (404, not_found):


{
    "message": "Deal not found."
}
 

Request      

PUT api/v1/deals/order

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the deal. Example: 1

Body Parameters

order   integer   

The new order position of the deal. Example: 3

column_id   integer   

The ID of the deal flow column. Example: 2

PUT api/v1/deals/{id}/order

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/deals/2070/order" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/deals/2070/order"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "PUT",
    headers,
}).then(response => response.json());

Request      

PUT api/v1/deals/{id}/order

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

The ID of the deal. Example: 2070

Email Campaigns

APIs for managing email marketing campaigns.

Email campaigns allow you to create scheduled email messages, configure their content (template or text editor), and send them to selected recipients.

Display a paginated list of email campaigns.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/email-campaigns?per_page=20&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/email-campaigns"
);

const params = {
    "per_page": "20",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 12,
            "user_id": 5,
            "team_id": 3,
            "email_template_id": 7,
            "name": "January Newsletter",
            "scheduled_at": "2025-02-01T10:00:00.000000Z",
            "email_type": "template",
            "text_editor": null,
            "created_at": "2025-01-20T08:30:00.000000Z",
            "updated_at": "2025-01-20T08:30:00.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/email-campaigns?page=1",
        "last": "https://example.com/api/v1/email-campaigns?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/email-campaigns",
        "per_page": 10,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/email-campaigns

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 20

sort   string  optional  

Column used for sorting. Allowed: created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Display a single email campaign.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/email-campaigns/12" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/email-campaigns/12"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 12,
    "user_id": 5,
    "team_id": 3,
    "email_template_id": 7,
    "name": "January Newsletter",
    "scheduled_at": "2025-02-01T10:00:00.000000Z",
    "email_type": "template",
    "text_editor": null,
    "created_at": "2025-01-20T08:30:00.000000Z",
    "updated_at": "2025-01-20T08:30:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/email-campaigns/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Email campaign id. Example: 12

Create a new email campaign.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/email-campaigns" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"January Newsletter\",
    \"scheduled_at\": \"2025-02-01T10:00:00Z\",
    \"email_type\": \"template\",
    \"email_template_id\": 7,
    \"text_editor\": \"Hello, this is our newsletter.\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/email-campaigns"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "January Newsletter",
    "scheduled_at": "2025-02-01T10:00:00Z",
    "email_type": "template",
    "email_template_id": 7,
    "text_editor": "Hello, this is our newsletter."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 12,
    "user_id": 5,
    "team_id": 3,
    "email_template_id": 7,
    "name": "January Newsletter",
    "scheduled_at": "2025-02-01T10:00:00.000000Z",
    "email_type": "template",
    "text_editor": null,
    "created_at": "2025-01-20T08:30:00.000000Z",
    "updated_at": "2025-01-20T08:30:00.000000Z"
}
 

Request      

POST api/v1/email-campaigns

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

Campaign name. Example: January Newsletter

scheduled_at   string   

ISO 8601 datetime when the campaign should be sent. Example: 2025-02-01T10:00:00Z

email_type   string   

Email type. Allowed: template, text_editor. Example: template

email_template_id   integer  optional  

required_if:email_type,template Template id. Example: 7

text_editor   string  optional  

required_if:email_type,text_editor Raw email content. Example: Hello, this is our newsletter.

Update an existing email campaign.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/email-campaigns/12" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"February Newsletter\",
    \"scheduled_at\": \"2025-02-15T10:00:00Z\",
    \"email_type\": \"text_editor\",
    \"email_template_id\": 7,
    \"text_editor\": \"architecto\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/email-campaigns/12"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "February Newsletter",
    "scheduled_at": "2025-02-15T10:00:00Z",
    "email_type": "text_editor",
    "email_template_id": 7,
    "text_editor": "architecto"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 12,
    "name": "February Newsletter",
    "email_type": "text_editor",
    "scheduled_at": "2025-02-15T10:00:00.000000Z",
    "updated_at": "2025-01-25T09:00:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/email-campaigns/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Email campaign id. Example: 12

Body Parameters

name   string  optional  

Campaign name. Example: February Newsletter

scheduled_at   string  optional  

ISO 8601 datetime. Example: 2025-02-15T10:00:00Z

email_type   string  optional  

Allowed: template, text_editor. Example: text_editor

email_template_id   integer  optional  

Template id. Example: 7

text_editor   string  optional  

Raw email content. Example: architecto

Delete an email campaign.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/email-campaigns/12" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/email-campaigns/12"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/email-campaigns/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Email campaign id. Example: 12

Send an email campaign.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/email-campaigns/12/send" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/email-campaigns/12/send"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "message": "Email campaign sent successfully"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

POST api/v1/email-campaigns/{id}/send

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Email campaign id. Example: 12

Email Templates

APIs for managing email templates.

Email templates are reusable messages that belong to a team and can be used for sending emails across the system.

Display a paginated list of email templates.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/email-templates?per_page=10&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/email-templates"
);

const params = {
    "per_page": "10",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 5,
            "template_name": "Invoice Reminder",
            "template_html": "<html>...</html>",
            "design_object": "{}",
            "created_at": "2025-01-15T10:00:00.000000Z",
            "updated_at": "2025-01-15T10:00:00.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/email-templates?page=1",
        "last": "https://example.com/api/v1/email-templates?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/email-templates",
        "per_page": 10,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/email-templates

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 10

sort   string  optional  

Column used for sorting. Allowed: created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Display a single email template.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/email-templates/5" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/email-templates/5"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 5,
    "template_name": "Invoice Reminder",
    "template_html": "<html>...</html>",
    "design_object": "{}",
    "created_at": "2025-01-15T10:00:00.000000Z",
    "updated_at": "2025-01-15T10:00:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/email-templates/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Email template id. Example: 5

Create a new email template.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/email-templates" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"template_name\": \"Invoice Reminder\",
    \"template_html\": \"<html>...<\\/html>\",
    \"design_object\": \"{}\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/email-templates"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "template_name": "Invoice Reminder",
    "template_html": "<html>...<\/html>",
    "design_object": "{}"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 5,
    "template_name": "Invoice Reminder",
    "template_html": "<html>...</html>",
    "design_object": "{}",
    "created_at": "2025-01-15T10:00:00.000000Z",
    "updated_at": "2025-01-15T10:00:00.000000Z"
}
 

Request      

POST api/v1/email-templates

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

template_name   string   

Template name. Example: Invoice Reminder

template_html   string   

HTML content of the template. Example: <html>...</html>

design_object   string   

Serialized design configuration. Example: {}

Update an existing email template.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/email-templates/5" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"template_name\": \"Updated Invoice Reminder\",
    \"template_html\": \"<html>updated<\\/html>\",
    \"design_object\": \"{}\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/email-templates/5"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "template_name": "Updated Invoice Reminder",
    "template_html": "<html>updated<\/html>",
    "design_object": "{}"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 5,
    "template_name": "Updated Invoice Reminder",
    "template_html": "<html>updated</html>",
    "design_object": "{}",
    "created_at": "2025-01-15T10:00:00.000000Z",
    "updated_at": "2025-01-15T11:30:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/email-templates/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Email template id. Example: 5

Body Parameters

template_name   string  optional  

Template name. Example: Updated Invoice Reminder

template_html   string  optional  

HTML content of the template. Example: <html>updated</html>

design_object   string  optional  

Serialized design configuration. Example: {}

Delete an email template.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/email-templates/5" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/email-templates/5"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/email-templates/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Email template id. Example: 5

Endpoints

Display a paginated list of invoices.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/invoices?search=INV-001&client_id=1&status=1&date_from=2024-01-01&date_to=2024-12-31&sort=created_at&direction=desc&per_page=25" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/invoices"
);

const params = {
    "search": "INV-001",
    "client_id": "1",
    "status": "1",
    "date_from": "2024-01-01",
    "date_to": "2024-12-31",
    "sort": "created_at",
    "direction": "desc",
    "per_page": "25",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "hash": "abc123def456",
            "currency_id": 1,
            "random_number": 123456,
            "status": 1,
            "exchange_coefficient": 1,
            "amount": 1000.5,
            "amount_base_currency": 1000.5,
            "paid_amount": 500,
            "paid_amount_base_currency": 500,
            "outstanding_amount": 500.5,
            "outstanding_amount_base_currency": 500.5,
            "client_id": 1,
            "user_id": 12,
            "team_id": 8,
            "from_company_id": null,
            "discount": 0,
            "tax1": 0,
            "tax2": 0,
            "issue_date": "2024-01-15",
            "due_date": "2024-02-15",
            "notes": "Invoice for development services",
            "number": "INV-001",
            "interval_date": null,
            "email": "[email protected]",
            "stripe_external_id": null,
            "stripe_invoice_url": null,
            "passim_invoice_url": null,
            "invoiced_at": "2024-01-15T10:30:00.000000Z",
            "created_at": "2024-01-15T10:30:00.000000Z",
            "updated_at": "2024-01-15T10:30:00.000000Z",
            "deleted_at": null,
            "payment_amount_paid": 500.5
        },
        {
            "id": 2,
            "hash": "def456ghi789",
            "currency_id": 1,
            "random_number": 789012,
            "status": 0,
            "exchange_coefficient": 1,
            "amount": 1500,
            "amount_base_currency": 1500,
            "paid_amount": 0,
            "paid_amount_base_currency": 0,
            "outstanding_amount": 1500,
            "outstanding_amount_base_currency": 1500,
            "client_id": 2,
            "user_id": 12,
            "team_id": 8,
            "from_company_id": null,
            "discount": 10,
            "tax1": 20,
            "tax2": 5,
            "issue_date": "2024-01-20",
            "due_date": "2024-02-20",
            "notes": "Monthly retainer invoice",
            "number": "INV-002",
            "interval_date": null,
            "email": "[email protected]",
            "stripe_external_id": null,
            "stripe_invoice_url": null,
            "passim_invoice_url": null,
            "invoiced_at": "2024-01-20T14:45:00.000000Z",
            "created_at": "2024-01-20T14:45:00.000000Z",
            "updated_at": "2024-01-20T14:45:00.000000Z",
            "deleted_at": null,
            "payment_amount_paid": 0
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/invoices?page=1",
        "last": "https://example.com/api/v1/invoices?page=3",
        "prev": null,
        "next": "https://example.com/api/v1/invoices?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "path": "https://example.com/api/v1/invoices",
        "per_page": 50,
        "to": 50,
        "total": 125
    }
}
 

Request      

GET api/v1/invoices

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Filter invoices by invoice number or client name. Example: INV-001

client_id   integer  optional  

Filter invoices by client ID. Example: 1

status   integer  optional  

Filter by status (0=draft, 1=sent, 2=closed, 3=cancelled, 4=open). Example: 1

date_from   string  optional  

date Filter by creation date (from). Format: YYYY-MM-DD. Example: 2024-01-01

date_to   string  optional  

date Filter by creation date (to). Format: YYYY-MM-DD. Example: 2024-12-31

sort   string  optional  

Column used for sorting. Allowed: id, number, amount, created_at, updated_at, issue_date, due_date. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

per_page   integer  optional  

Number of results per page. Maximum: 100. Default: 50. Example: 25

Create a new invoice.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/invoices" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"client_id\": 1,
    \"currency_id\": 1,
    \"status\": 0,
    \"amount\": \"1000.50\",
    \"issue_date\": \"2024-01-15\",
    \"due_date\": \"2024-02-15\",
    \"notes\": \"\\\"Invoice for development services\\\"\",
    \"number\": \"\\\"INV-001\\\"\",
    \"discount\": 10,
    \"tax1\": 20,
    \"tax2\": 5,
    \"email\": \"\\\"[email protected]\\\"\",
    \"items\": [
        \"architecto\"
    ]
}"
const url = new URL(
    "https://app.corcava.com/api/v1/invoices"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "client_id": 1,
    "currency_id": 1,
    "status": 0,
    "amount": "1000.50",
    "issue_date": "2024-01-15",
    "due_date": "2024-02-15",
    "notes": "\"Invoice for development services\"",
    "number": "\"INV-001\"",
    "discount": 10,
    "tax1": 20,
    "tax2": 5,
    "email": "\"[email protected]\"",
    "items": [
        "architecto"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "data": {
        "id": 3,
        "hash": "ghi789jkl012",
        "currency_id": 1,
        "random_number": 345678,
        "status": 0,
        "exchange_coefficient": 1,
        "amount": 1000.5,
        "amount_base_currency": 1000.5,
        "paid_amount": 0,
        "paid_amount_base_currency": 0,
        "outstanding_amount": 1000.5,
        "outstanding_amount_base_currency": 1000.5,
        "client_id": 1,
        "user_id": 12,
        "team_id": 8,
        "from_company_id": null,
        "discount": 10,
        "tax1": 20,
        "tax2": 5,
        "issue_date": "2024-01-15",
        "due_date": "2024-02-15",
        "notes": "Invoice for development services",
        "number": "INV-003",
        "interval_date": null,
        "email": "[email protected]",
        "stripe_external_id": null,
        "stripe_invoice_url": null,
        "passim_invoice_url": null,
        "invoiced_at": "2024-01-15T10:30:00.000000Z",
        "created_at": "2024-01-15T10:30:00.000000Z",
        "updated_at": "2024-01-15T10:30:00.000000Z",
        "deleted_at": null,
        "payment_amount_paid": 0,
        "items": [
            {
                "id": 3,
                "name": "Feature development",
                "price": 100,
                "quantity": 10,
                "amount": 1000,
                "invoice_id": 3
            },
            {
                "id": 4,
                "name": "API Integration",
                "price": 0.5,
                "quantity": 1,
                "amount": 0.5,
                "invoice_id": 3
            }
        ]
    }
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "client_id": [
            "The client id field is required."
        ],
        "amount": [
            "The amount field is required."
        ]
    }
}
 

Request      

POST api/v1/invoices

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

client_id   integer   

Client ID. Example: 1

currency_id   integer  optional  

Currency ID. Defaults to client's currency. Example: 1

status   integer  optional  

Invoice status (0=draft, 1=sent, 2=closed, 3=cancelled, 4=open). Default: 0. Example: 0

amount   numeric   

Invoice total amount. Example: 1000.50

issue_date   date   

Issue date. Format: YYYY-MM-DD. Example: 2024-01-15

due_date   date   

Due date. Format: YYYY-MM-DD. Example: 2024-02-15

notes   string  optional  

Internal notes. Example: "Invoice for development services"

number   string  optional  

Invoice number. Auto-generated if not provided. Example: "INV-001"

discount   integer  optional  

Discount percentage. Example: 10

tax1   integer  optional  

First tax percentage. Example: 20

tax2   integer  optional  

Second tax percentage. Example: 5

email   string  optional  

Client email for sending invoice. Example: "[email protected]"

items   string[]  optional  

Invoice line items.

*   object  optional  
name   string   

Item name. Example: "Feature development"

price   numeric   

Unit price. Example: 100

quantity   numeric   

Quantity. Example: 10

amount   numeric   

Item amount. Example: 1000

Display a single invoice with items.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/invoices/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/invoices/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": {
        "id": 1,
        "hash": "abc123def456",
        "currency_id": 1,
        "random_number": 123456,
        "status": 1,
        "exchange_coefficient": 1,
        "amount": 1000.5,
        "amount_base_currency": 1000.5,
        "paid_amount": 500,
        "paid_amount_base_currency": 500,
        "outstanding_amount": 500.5,
        "outstanding_amount_base_currency": 500.5,
        "client_id": 1,
        "user_id": 12,
        "team_id": 8,
        "from_company_id": null,
        "discount": 0,
        "tax1": 0,
        "tax2": 0,
        "issue_date": "2024-01-15",
        "due_date": "2024-02-15",
        "notes": "Invoice for development services",
        "number": "INV-001",
        "interval_date": null,
        "email": "[email protected]",
        "stripe_external_id": null,
        "stripe_invoice_url": null,
        "passim_invoice_url": null,
        "invoiced_at": "2024-01-15T10:30:00.000000Z",
        "created_at": "2024-01-15T10:30:00.000000Z",
        "updated_at": "2024-01-15T10:30:00.000000Z",
        "deleted_at": null,
        "payment_amount_paid": 500.5,
        "items": [
            {
                "id": 1,
                "name": "Feature development",
                "price": 100,
                "quantity": 10,
                "amount": 1000,
                "invoice_id": 1
            },
            {
                "id": 2,
                "name": "API Integration",
                "price": 0.5,
                "quantity": 1,
                "amount": 0.5,
                "invoice_id": 1
            }
        ]
    }
}
 

Example response (404, not_found):


{
    "message": "Invoice not found"
}
 

Request      

GET api/v1/invoices/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Invoice ID. Example: 1

Update an existing invoice.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/invoices/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"client_id\": 2,
    \"currency_id\": 2,
    \"status\": 1,
    \"amount\": \"1200.00\",
    \"issue_date\": \"2024-01-16\",
    \"due_date\": \"2024-02-16\",
    \"notes\": \"\\\"Updated invoice\\\"\",
    \"number\": \"\\\"INV-001-REV\\\"\",
    \"discount\": 15,
    \"tax1\": 18,
    \"tax2\": 3,
    \"email\": \"\\\"[email protected]\\\"\",
    \"items\": [
        \"architecto\"
    ]
}"
const url = new URL(
    "https://app.corcava.com/api/v1/invoices/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "client_id": 2,
    "currency_id": 2,
    "status": 1,
    "amount": "1200.00",
    "issue_date": "2024-01-16",
    "due_date": "2024-02-16",
    "notes": "\"Updated invoice\"",
    "number": "\"INV-001-REV\"",
    "discount": 15,
    "tax1": 18,
    "tax2": 3,
    "email": "\"[email protected]\"",
    "items": [
        "architecto"
    ]
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "data": {
        "id": 1,
        "hash": "abc123def456",
        "currency_id": 2,
        "random_number": 123456,
        "status": 1,
        "exchange_coefficient": 1,
        "amount": 1200,
        "amount_base_currency": 1200,
        "paid_amount": 500,
        "paid_amount_base_currency": 500,
        "outstanding_amount": 700,
        "outstanding_amount_base_currency": 700,
        "client_id": 2,
        "user_id": 12,
        "team_id": 8,
        "from_company_id": null,
        "discount": 15,
        "tax1": 18,
        "tax2": 3,
        "issue_date": "2024-01-16",
        "due_date": "2024-02-16",
        "notes": "Updated invoice",
        "number": "INV-001-REV",
        "interval_date": null,
        "email": "[email protected]",
        "stripe_external_id": null,
        "stripe_invoice_url": null,
        "passim_invoice_url": null,
        "invoiced_at": "2024-01-15T10:30:00.000000Z",
        "created_at": "2024-01-15T10:30:00.000000Z",
        "updated_at": "2024-01-16T14:20:00.000000Z",
        "deleted_at": null,
        "payment_amount_paid": 500.5,
        "items": [
            {
                "id": 5,
                "name": "Updated development",
                "price": 120,
                "quantity": 10,
                "amount": 1200,
                "invoice_id": 1
            }
        ]
    }
}
 

Example response (404, not_found):


{
    "message": "Invoice not found"
}
 

Request      

PUT api/v1/invoices/{id}

PATCH api/v1/invoices/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Invoice ID. Example: 1

Body Parameters

client_id   integer  optional  

Client ID. Example: 2

currency_id   integer  optional  

Currency ID. Example: 2

status   integer  optional  

Invoice status (0-4). Example: 1

amount   numeric  optional  

Invoice total amount. Example: 1200.00

issue_date   date  optional  

Issue date. Format: YYYY-MM-DD. Example: 2024-01-16

due_date   date  optional  

Due date. Format: YYYY-MM-DD. Example: 2024-02-16

notes   string  optional  

Internal notes. Example: "Updated invoice"

number   string  optional  

Invoice number. Example: "INV-001-REV"

discount   integer  optional  

Discount percentage. Example: 15

tax1   integer  optional  

First tax percentage. Example: 18

tax2   integer  optional  

Second tax percentage. Example: 3

email   string  optional  

Client email. Example: "[email protected]"

items   string[]  optional  

Invoice line items (replaces all existing items).

*   object  optional  
name   string   

Item name. Example: "Updated development"

price   numeric   

Unit price. Example: 120

quantity   numeric   

Quantity. Example: 10

amount   numeric   

Item amount. Example: 1200

Delete an invoice (soft delete).

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/invoices/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/invoices/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "message": "Invoice deleted successfully"
}
 

Example response (404, not_found):


{
    "message": "Invoice not found"
}
 

Request      

DELETE api/v1/invoices/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Invoice ID. Example: 1

Update invoice status.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/invoices/1/status" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"status\": 1
}"
const url = new URL(
    "https://app.corcava.com/api/v1/invoices/1/status"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "status": 1
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "data": {
        "id": 1,
        "hash": "abc123def456",
        "number": "INV-001",
        "status": 1,
        "amount": 1000.5,
        "client_id": 1,
        "issue_date": "2024-01-15",
        "due_date": "2024-02-15",
        "created_at": "2024-01-15T10:30:00.000000Z",
        "updated_at": "2024-01-16T16:45:00.000000Z"
    },
    "message": "Invoice status updated successfully"
}
 

Example response (404, not_found):


{
    "message": "Invoice not found"
}
 

Example response (422, invalid_transition):


{
    "message": "Cannot change status from closed to draft"
}
 

Request      

PUT api/v1/invoices/{id}/status

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Invoice ID. Example: 1

Body Parameters

status   integer   

New invoice status (0=draft, 1=sent, 2=closed, 3=cancelled, 4=open). Example: 1

Send an invoice to client.

requires authentication

Updates invoice status to "sent" (1)

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/invoices/1/send" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/invoices/1/send"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "message": "Invoice sent successfully"
}
 

Example response (404, not_found):


{
    "message": "Invoice not found"
}
 

Example response (422, no_recipient):


{
    "message": "No valid recipient email for this invoice; set invoice email or client email."
}
 

Example response (500, mail_failed):


{
    "message": "Unable to send invoice email"
}
 

Request      

POST api/v1/invoices/{id}/send

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Invoice ID. Example: 1

Create a CRM email draft to follow up on an invoice (does not send).

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/invoices/MBJkCmaYOiAmXn9/followup-draft" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"subject\": \"b\",
    \"message\": \"n\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/invoices/MBJkCmaYOiAmXn9/followup-draft"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "subject": "b",
    "message": "n"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/v1/invoices/{id}/followup-draft

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the invoice. Example: MBJkCmaYOiAmXn9

Body Parameters

subject   string  optional  

Must not be greater than 500 characters. Example: b

message   string  optional  

Must not be greater than 50000 characters. Example: n

Record a payment for an invoice.

requires authentication

Creates a payment record and updates invoice paid/outstanding amounts. If invoice becomes fully paid, status is automatically updated to "closed" (2).

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/invoices/1/payment" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"amount_paid\": \"500.00\",
    \"payment_date\": \"2024-01-20\",
    \"notes\": \"\\\"Bank transfer - Reference: INV001\\\"\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/invoices/1/payment"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "amount_paid": "500.00",
    "payment_date": "2024-01-20",
    "notes": "\"Bank transfer - Reference: INV001\""
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "message": "Payment recorded successfully",
    "payment": {
        "id": 1,
        "invoice_id": 1,
        "currency_id": 1,
        "exchange_coefficient": 1,
        "amount_paid": 500,
        "amount_paid_base_currency": 500,
        "payment_date": "2024-01-20",
        "notes": "Bank transfer - Reference: INV001",
        "created_at": "2024-01-20T10:15:00.000000Z",
        "updated_at": "2024-01-20T10:15:00.000000Z"
    }
}
 

Example response (404, not_found):


{
    "message": "Invoice not found"
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "amount_paid": [
            "The amount paid must be greater than 0."
        ]
    }
}
 

Request      

POST api/v1/invoices/{id}/payment

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Invoice ID. Example: 1

Body Parameters

amount_paid   numeric   

Payment amount. Example: 500.00

payment_date   date   

Payment date. Format: YYYY-MM-DD. Example: 2024-01-20

notes   string  optional  

optional Payment notes. Example: "Bank transfer - Reference: INV001"

POST api/v1/spreadsheet-import/previews/{publicId}/apply

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/spreadsheet-import/previews/BcECdBDA-CdED-bFEA-CbCE-BcCdeBfbbebc/apply" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/spreadsheet-import/previews/BcECdBDA-CdED-bFEA-CbCE-BcCdeBfbbebc/apply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/v1/spreadsheet-import/previews/{publicId}/apply

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

publicId   string   

Example: BcECdBDA-CdED-bFEA-CbCE-BcCdeBfbbebc

Expenses

APIs for managing business expenses.

Track business expenses with support for categorization, project assignment, and file attachments. All expenses are scoped to the authenticated user's team.

List expenses

requires authentication

Display a paginated list of expenses with optional filtering and sorting.

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/expenses?user_id=12&project_id=5&per_page=50&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/expenses"
);

const params = {
    "user_id": "12",
    "project_id": "5",
    "per_page": "50",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 15,
            "description": "Office supplies",
            "date": "2024-01-15",
            "user_id": 12,
            "team_id": 8,
            "category": "Office Expenses",
            "amount": 145.5,
            "notes": "Purchased notebooks and pens",
            "billable": true,
            "file_url": "https://example.com/receipts/receipt-15.pdf",
            "project_id": 5,
            "created_at": "2024-01-15T14:30:00.000000Z",
            "updated_at": "2024-01-15T14:30:00.000000Z",
            "deleted_at": null
        },
        {
            "id": 16,
            "description": "Business lunch",
            "date": "2024-01-14",
            "user_id": 12,
            "team_id": 8,
            "category": "Meals & Entertainment",
            "amount": 89.75,
            "notes": "Client meeting at restaurant",
            "billable": true,
            "file_url": null,
            "project_id": null,
            "created_at": "2024-01-14T19:45:00.000000Z",
            "updated_at": "2024-01-14T19:45:00.000000Z",
            "deleted_at": null
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/expenses?page=1",
        "last": "https://example.com/api/v1/expenses?page=3",
        "prev": null,
        "next": "https://example.com/api/v1/expenses?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "path": "https://example.com/api/v1/expenses",
        "per_page": 30,
        "to": 30,
        "total": 75
    }
}
 

Request      

GET api/v1/expenses

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

user_id   integer  optional  

Filter expenses by user id. Example: 12

project_id   integer  optional  

Filter expenses by project id. Example: 5

per_page   integer  optional  

Number of results per page. Minimum: 1, Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, user_id, project_id, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create expense

requires authentication

Create a new business expense record.

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/expenses" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"description\": \"Office supplies\",
    \"date\": \"2024-01-15\",
    \"user_id\": 12,
    \"category\": \"Office Expenses\",
    \"amount\": \"145.50\",
    \"notes\": \"Purchased notebooks and pens\",
    \"billable\": true,
    \"file_url\": \"https:\\/\\/example.com\\/receipts\\/receipt-15.pdf\",
    \"project_id\": 5,
    \"team_id\": \"architecto\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/expenses"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "description": "Office supplies",
    "date": "2024-01-15",
    "user_id": 12,
    "category": "Office Expenses",
    "amount": "145.50",
    "notes": "Purchased notebooks and pens",
    "billable": true,
    "file_url": "https:\/\/example.com\/receipts\/receipt-15.pdf",
    "project_id": 5,
    "team_id": "architecto"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "data": {
        "id": 15,
        "description": "Office supplies",
        "date": "2024-01-15",
        "user_id": 12,
        "team_id": 8,
        "category": "Office Expenses",
        "amount": 145.5,
        "notes": "Purchased notebooks and pens",
        "billable": true,
        "file_url": "https://example.com/receipts/receipt-15.pdf",
        "project_id": 5,
        "created_at": "2024-01-15T14:30:00.000000Z",
        "updated_at": "2024-01-15T14:30:00.000000Z",
        "deleted_at": null
    },
    "message": "Expense created successfully"
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "date": [
            "The date field is required."
        ],
        "amount": [
            "The amount field is required."
        ]
    }
}
 

Request      

POST api/v1/expenses

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

description   string  optional  

Expense description. Example: Office supplies

date   date   

Expense date (YYYY-MM-DD). Example: 2024-01-15

user_id   integer  optional  

User id for the expense. Defaults to the authenticated user. Example: 12

category   string   

Expense category. Example: Office Expenses

amount   numeric   

Expense amount. Must be positive. Example: 145.50

notes   string  optional  

Additional notes. Example: Purchased notebooks and pens

billable   boolean  optional  

Indicates if the expense is billable to a client. Example: true

file_url   string  optional  

URL to attached receipt or document. Example: https://example.com/receipts/receipt-15.pdf

project_id   integer  optional  

Project id to associate with the expense. Example: 5

team_id   string  optional  

Prohibited. Automatically set to the user's team. Example: architecto

Update expense

requires authentication

Update an existing expense record. Expenses linked to an invoice cannot be edited.

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/expenses/15" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"description\": \"Updated office supplies\",
    \"date\": \"2024-01-16\",
    \"user_id\": 13,
    \"category\": \"Updated Office Expenses\",
    \"amount\": \"150.00\",
    \"notes\": \"Added printer paper\",
    \"billable\": false,
    \"file_url\": \"https:\\/\\/example.com\\/receipts\\/receipt-15-updated.pdf\",
    \"project_id\": 6,
    \"team_id\": \"architecto\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/expenses/15"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "description": "Updated office supplies",
    "date": "2024-01-16",
    "user_id": 13,
    "category": "Updated Office Expenses",
    "amount": "150.00",
    "notes": "Added printer paper",
    "billable": false,
    "file_url": "https:\/\/example.com\/receipts\/receipt-15-updated.pdf",
    "project_id": 6,
    "team_id": "architecto"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "data": {
        "id": 15,
        "description": "Updated office supplies",
        "date": "2024-01-16",
        "user_id": 12,
        "team_id": 8,
        "category": "Updated Office Expenses",
        "amount": 150,
        "notes": "Added printer paper",
        "billable": false,
        "file_url": "https://example.com/receipts/receipt-15-updated.pdf",
        "project_id": 6,
        "created_at": "2024-01-15T14:30:00.000000Z",
        "updated_at": "2024-01-16T10:15:00.000000Z",
        "deleted_at": null
    },
    "message": "Expense updated successfully"
}
 

Example response (404, not_found):


{
    "message": "Expense not found"
}
 

Example response (422, invoice_linked):


{
    "message": "Expenses with an invoice cannot be edited"
}
 

Request      

PUT api/v1/expenses/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Expense id. Example: 15

Body Parameters

description   string  optional  

Expense description. Example: Updated office supplies

date   date  optional  

Expense date (YYYY-MM-DD). Example: 2024-01-16

user_id   integer  optional  

User id for the expense. Example: 13

category   string  optional  

Expense category. Example: Updated Office Expenses

amount   numeric  optional  

Expense amount. Must be positive. Example: 150.00

notes   string  optional  

Additional notes. Example: Added printer paper

billable   boolean  optional  

Indicates if the expense is billable to a client. Example: false

file_url   string  optional  

URL to attached receipt or document. Example: https://example.com/receipts/receipt-15-updated.pdf

project_id   integer  optional  

Project id to associate with the expense. Example: 6

team_id   string  optional  

Prohibited. Automatically set to the user's team. Example: architecto

Delete expense

requires authentication

Delete an expense record.

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/expenses/15" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/expenses/15"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "message": "Expense deleted successfully"
}
 

Example response (404, not_found):


{
    "message": "Expense not found"
}
 

Request      

DELETE api/v1/expenses/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Expense id. Example: 15

HR Candidates

Public API for managing HR candidates.

Candidates belong to HR vacancies and are always scoped to the authenticated user's team.

List candidates for a vacancy.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/hr/vacancies/5/candidates?per_page=30&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/vacancies/5/candidates"
);

const params = {
    "per_page": "30",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "name": "John Doe",
            "slug": "john-doe",
            "profile_url": "https://linkedin.com/in/johndoe",
            "hr_vacancy_id": 5,
            "hr_vacancy_column_id": 2,
            "created_at": "2025-01-10T08:00:00.000000Z",
            "updated_at": "2025-01-10T08:00:00.000000Z"
        }
    ],
    "meta": {
        "current_page": 1,
        "per_page": 30,
        "total": 1
    }
}
 

Request      

GET api/v1/hr/vacancies/{vacancy}/candidates

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

vacancy   integer   

HR vacancy ID. Example: 5

Query Parameters

per_page   integer  optional  

Number of items per page (max 100). Example: 30

sort   string  optional  

Sort column. Allowed: id, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Show a candidate.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/hr/candidates/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/candidates/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 1,
    "name": "John Doe",
    "slug": "john-doe",
    "profile_url": "https://linkedin.com/in/johndoe",
    "hr_vacancy_id": 5,
    "hr_vacancy_column_id": 2,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/hr/candidates/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Candidate ID. Example: 1

Create a candidate.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/hr/candidates" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"John Doe\",
    \"profile_url\": \"https:\\/\\/linkedin.com\\/in\\/johndoe\",
    \"hr_vacancy_id\": 5,
    \"hr_vacancy_column_id\": 2
}"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/candidates"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "John Doe",
    "profile_url": "https:\/\/linkedin.com\/in\/johndoe",
    "hr_vacancy_id": 5,
    "hr_vacancy_column_id": 2
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 1,
    "name": "John Doe",
    "slug": "john-doe",
    "profile_url": "https://linkedin.com/in/johndoe",
    "hr_vacancy_id": 5,
    "hr_vacancy_column_id": 2,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z"
}
 

Request      

POST api/v1/hr/candidates

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

Candidate name. Example: John Doe

profile_url   string   

Candidate profile URL. Example: https://linkedin.com/in/johndoe

hr_vacancy_id   integer   

HR vacancy ID. Example: 5

hr_vacancy_column_id   integer  optional  

HR vacancy column ID. Example: 2

Update a candidate.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/hr/candidates/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"John Doe\",
    \"profile_url\": \"https:\\/\\/linkedin.com\\/in\\/johndoe\",
    \"hr_vacancy_id\": 5,
    \"hr_vacancy_column_id\": 2
}"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/candidates/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "John Doe",
    "profile_url": "https:\/\/linkedin.com\/in\/johndoe",
    "hr_vacancy_id": 5,
    "hr_vacancy_column_id": 2
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 1,
    "name": "John Doe",
    "slug": "john-doe",
    "profile_url": "https://linkedin.com/in/johndoe",
    "hr_vacancy_id": 5,
    "hr_vacancy_column_id": 2,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-11T10:30:00.000000Z"
}
 

Request      

PUT api/v1/hr/candidates/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Candidate ID. Example: 1

Body Parameters

name   string  optional  

Candidate name. Example: John Doe

profile_url   string  optional  

Candidate profile URL. Example: https://linkedin.com/in/johndoe

hr_vacancy_id   integer  optional  

HR vacancy ID. Example: 5

hr_vacancy_column_id   integer  optional  

HR vacancy column ID. Example: 2

Delete a candidate.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/hr/candidates/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/candidates/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/hr/candidates/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Candidate ID. Example: 1

Add a comment to a candidate.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/hr/candidates/1/comments" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"comment\": \"Had a great interview.\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/candidates/1/comments"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "comment": "Had a great interview."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "message": "Comment added successfully"
}
 

Request      

POST api/v1/hr/candidates/{id}/comments

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Candidate ID. Example: 1

Body Parameters

comment   string   

Comment text. Example: Had a great interview.

HR Interviews

APIs for managing HR interviews.

HR interviews represent scheduled or conducted interviews within your team.

Store a newly created HrInterview in storage.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/hr/interviews" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"hr_candidate_id\": 1,
    \"interviewer_user_id\": 2,
    \"from\": \"architecto\",
    \"to\": \"architecto\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/interviews"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "hr_candidate_id": 1,
    "interviewer_user_id": 2,
    "from": "architecto",
    "to": "architecto"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, Success):


{
    "id": 1,
    "user_id": 3,
    "team_id": 1,
    "interviewer_user_id": 2,
    "from": "2024-07-01T10:00:00Z",
    "to": "2024-07-01T11:00:00Z",
    "created_at": "2024-06-15T12:00:00Z",
    "updated_at": "2024-06-15T12:00:00Z"
}
 

Request      

POST api/v1/hr/interviews

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

hr_candidate_id   integer   

The ID of the HR candidate. Example: 1

interviewer_user_id   integer   

The ID of the interviewer user. Example: 2

from   string   

The start date and time of the interview. Example: architecto

to   string   

The end date and time of the interview. Example: architecto

Response

Response Fields

id   integer   

The ID of the created HR interview.

user_id   integer   

The ID of the user who created the interview.

team_id   integer   

The ID of the team associated with the interview.

HR Vacancies

APIs for managing HR vacancies.

Vacancies represent open job positions within a team. These endpoints allow authenticated users to list, view, create, update, and delete vacancies belonging to their team.

Display a paginated list of vacancies.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/hr/vacancies?per_page=30&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"per_page\": 1,
    \"sort\": \"id\",
    \"direction\": \"asc\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/vacancies"
);

const params = {
    "per_page": "30",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "per_page": 1,
    "sort": "id",
    "direction": "asc"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 10,
            "title": "Senior PHP Developer",
            "slug": "senior-php-developer",
            "description": "We are looking for an experienced PHP developer.",
            "requirements": "5+ years of PHP, Laravel experience",
            "created_at": "2025-01-10T08:00:00.000000Z",
            "updated_at": "2025-01-10T08:00:00.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/hr/vacancies?page=1",
        "last": "https://example.com/api/v1/hr/vacancies?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/hr/vacancies",
        "per_page": 30,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/hr/vacancies

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 30

sort   string  optional  

Column used for sorting. Allowed: id, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Body Parameters

per_page   integer  optional  

Must be at least 1. Must not be greater than 100. Example: 1

sort   string  optional  

Example: id

Must be one of:
  • id
  • created_at
  • updated_at
direction   string  optional  

Example: asc

Must be one of:
  • asc
  • desc

Display a single vacancy.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/hr/vacancies/10" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/vacancies/10"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 10,
    "title": "Senior PHP Developer",
    "slug": "senior-php-developer",
    "description": "We are looking for an experienced PHP developer.",
    "requirements": "5+ years of PHP, Laravel experience",
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/hr/vacancies/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Vacancy id. Example: 10

Create a new vacancy.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/hr/vacancies" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"title\": \"Senior PHP Developer\",
    \"requirements\": \"5+ years of PHP, Laravel experience\",
    \"description\": \"We are looking for an experienced PHP developer.\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/vacancies"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "title": "Senior PHP Developer",
    "requirements": "5+ years of PHP, Laravel experience",
    "description": "We are looking for an experienced PHP developer."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 10,
    "title": "Senior PHP Developer",
    "slug": "senior-php-developer",
    "description": "We are looking for an experienced PHP developer.",
    "requirements": "5+ years of PHP, Laravel experience",
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z"
}
 

Request      

POST api/v1/hr/vacancies

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

title   string   

Vacancy title. Example: Senior PHP Developer

team_id   string  optional  
requirements   string  optional  

Job requirements. Example: 5+ years of PHP, Laravel experience

description   string  optional  

Vacancy description. Example: We are looking for an experienced PHP developer.

Update an existing vacancy.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/hr/vacancies/10" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"title\": \"Senior PHP Developer\",
    \"requirements\": \"Strong Laravel and REST API knowledge\",
    \"description\": \"Updated description.\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/vacancies/10"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "title": "Senior PHP Developer",
    "requirements": "Strong Laravel and REST API knowledge",
    "description": "Updated description."
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 10,
    "title": "Senior PHP Developer",
    "slug": "senior-php-developer",
    "description": "Updated description.",
    "requirements": "Strong Laravel and REST API knowledge",
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T12:00:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/hr/vacancies/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Vacancy id. Example: 10

Body Parameters

title   string  optional  

Vacancy title. Example: Senior PHP Developer

team_id   string  optional  
requirements   string  optional  

Job requirements. Example: Strong Laravel and REST API knowledge

description   string  optional  

Vacancy description. Example: Updated description.

Delete a vacancy.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/hr/vacancies/10" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/hr/vacancies/10"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/hr/vacancies/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Vacancy id. Example: 10

Healthcheck

Checking API availability

Ping API

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/ping" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/ping"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
  'message' => 'pong'
}
 

Request      

GET api/v1/ping

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Meetings

APIs for managing calendar meetings.

Meetings represent scheduled events within a team. These endpoints allow you to list, create, update, and delete meetings associated with your team.

Display a paginated list of meetings.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/meetings?user_id=12&per_page=20&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"user_id\": 16,
    \"per_page\": 22,
    \"sort\": \"created_at\",
    \"direction\": \"desc\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/meetings"
);

const params = {
    "user_id": "12",
    "per_page": "20",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "user_id": 16,
    "per_page": 22,
    "sort": "created_at",
    "direction": "desc"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 5,
            "name": "Project kickoff",
            "from": "2025-02-01T09:00:00.000000Z",
            "to": "2025-02-01T10:00:00.000000Z",
            "user_id": 12,
            "team_id": 8,
            "location": "Zoom",
            "meeting_url": "https://zoom.us/j/123456789",
            "description": "Initial project discussion",
            "created_at": "2025-01-20T08:00:00.000000Z",
            "updated_at": "2025-01-20T08:00:00.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/meetings?page=1",
        "last": "https://example.com/api/v1/meetings?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/meetings",
        "per_page": 10,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/meetings

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

user_id   integer  optional  

Filter meetings by owner id. Example: 12

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 20

sort   string  optional  

Column used for sorting. Allowed: id, name, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Body Parameters

user_id   integer  optional  

The id of an existing record in the users table. Example: 16

per_page   integer  optional  

Must be at least 1. Must not be greater than 100. Example: 22

sort   string  optional  

Example: created_at

Must be one of:
  • id
  • name
  • created_at
  • updated_at
direction   string  optional  

Example: desc

Must be one of:
  • asc
  • desc

Create a new meeting.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/meetings" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Sprint planning\",
    \"guest_email\": \"[email protected]\",
    \"guest_timezone\": \"Europe\\/Berlin\",
    \"location\": \"Office room 3\",
    \"meeting_url\": \"https:\\/\\/meet.google.com\\/abc-defg-hij\",
    \"description\": \"Discuss sprint scope\",
    \"from\": \"2025-02-01T09:00:00Z\",
    \"to\": \"2025-02-01T10:00:00Z\",
    \"add_to_calendar\": false,
    \"client_timezone\": \"Asia\\/Ulaanbaatar\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/meetings"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Sprint planning",
    "guest_email": "[email protected]",
    "guest_timezone": "Europe\/Berlin",
    "location": "Office room 3",
    "meeting_url": "https:\/\/meet.google.com\/abc-defg-hij",
    "description": "Discuss sprint scope",
    "from": "2025-02-01T09:00:00Z",
    "to": "2025-02-01T10:00:00Z",
    "add_to_calendar": false,
    "client_timezone": "Asia\/Ulaanbaatar"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 5,
    "name": "Sprint planning",
    "from": "2025-02-01T09:00:00.000000Z",
    "to": "2025-02-01T10:00:00.000000Z",
    "user_id": 12,
    "team_id": 8,
    "location": "Office room 3",
    "meeting_url": null,
    "description": "Discuss sprint scope",
    "created_at": "2025-01-20T08:00:00.000000Z",
    "updated_at": "2025-01-20T08:00:00.000000Z"
}
 

Request      

POST api/v1/meetings

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

Meeting title. Example: Sprint planning

user_id   string  optional  
team_id   string  optional  
guest_email   string  optional  

Guest email address. Example: [email protected]

guest_timezone   string  optional  

Guest timezone. Example: Europe/Berlin

location   string  optional  

Meeting location. Example: Office room 3

meeting_url   string  optional  

Online meeting URL. Example: https://meet.google.com/abc-defg-hij

description   string  optional  

Meeting description. Example: Discuss sprint scope

from   string   

Start datetime (ISO 8601). Example: 2025-02-01T09:00:00Z

to   string   

End datetime (ISO 8601). Example: 2025-02-01T10:00:00Z

add_to_calendar   boolean  optional  

Example: false

client_timezone   string   

Must be a valid time zone, such as Africa/Accra. Example: Asia/Ulaanbaatar

Update an existing meeting.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/meetings/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Updated meeting title\",
    \"guest_email\": \"[email protected]\",
    \"guest_timezone\": \"America\\/Moncton\",
    \"location\": \"Zoom\",
    \"meeting_url\": \"https:\\/\\/zoom.us\\/j\\/123456789\",
    \"description\": \"Updated agenda\",
    \"from\": \"2025-02-01T10:00:00Z\",
    \"to\": \"2025-02-01T11:00:00Z\",
    \"add_to_calendar\": false,
    \"client_timezone\": \"Asia\\/Ulaanbaatar\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/meetings/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Updated meeting title",
    "guest_email": "[email protected]",
    "guest_timezone": "America\/Moncton",
    "location": "Zoom",
    "meeting_url": "https:\/\/zoom.us\/j\/123456789",
    "description": "Updated agenda",
    "from": "2025-02-01T10:00:00Z",
    "to": "2025-02-01T11:00:00Z",
    "add_to_calendar": false,
    "client_timezone": "Asia\/Ulaanbaatar"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 5,
    "name": "Updated meeting title",
    "from": "2025-02-01T10:00:00.000000Z",
    "to": "2025-02-01T11:00:00.000000Z",
    "user_id": 12,
    "team_id": 8,
    "location": "Zoom",
    "meeting_url": "https://zoom.us/j/123456789",
    "description": "Updated agenda",
    "created_at": "2025-01-20T08:00:00.000000Z",
    "updated_at": "2025-01-21T09:30:00.000000Z"
}
 

Request      

PUT api/v1/meetings/{meeting_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

meeting_id   integer   

The ID of the meeting. Example: 1

meeting   integer   

Meeting id. Example: 5

Body Parameters

name   string  optional  

Meeting title. Example: Updated meeting title

user_id   string  optional  
team_id   string  optional  
guest_email   string  optional  

Must be a valid email address. Must not be greater than 255 characters. Example: [email protected]

guest_timezone   string  optional  

Must be a valid time zone, such as Africa/Accra. Example: America/Moncton

location   string  optional  

Meeting location. Example: Zoom

meeting_url   string  optional  

Online meeting URL. Example: https://zoom.us/j/123456789

description   string  optional  

Meeting description. Example: Updated agenda

from   string  optional  

Start datetime (ISO 8601). Example: 2025-02-01T10:00:00Z

to   string  optional  

End datetime (ISO 8601). Example: 2025-02-01T11:00:00Z

add_to_calendar   boolean  optional  

Example: false

client_timezone   string   

Must be a valid time zone, such as Africa/Accra. Example: Asia/Ulaanbaatar

Delete a meeting.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/meetings/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/meetings/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Request      

DELETE api/v1/meetings/{meeting_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

meeting_id   integer   

The ID of the meeting. Example: 1

meeting   integer   

Meeting id. Example: 5

Outreach

APIs for managing outreach activities.

Outreach activities represent sales outreach efforts like calls, emails, and social media interactions. These endpoints let you list, create, update, and delete outreach activities for your team.

Display a paginated list of outreach activities.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/outreach?type=1&user_id=12&search=prospect&date_from=2024-01-01&date_to=2024-12-31&per_page=50&sort=datetime&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/outreach"
);

const params = {
    "type": "1",
    "user_id": "12",
    "search": "prospect",
    "date_from": "2024-01-01",
    "date_to": "2024-12-31",
    "per_page": "50",
    "sort": "datetime",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 4,
            "type": 1,
            "value": "Initial contact",
            "email": "[email protected]",
            "phone": "+1 202 555 0147",
            "user_id": 12,
            "team_id": 8,
            "description": "Initial outreach via email",
            "datetime": "2024-01-10T08:00:00.000000Z",
            "created_at": "2024-01-10T08:00:00.000000Z",
            "updated_at": "2024-01-10T08:00:00.000000Z",
            "deleted_at": null
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/outreach?page=1",
        "last": "https://example.com/api/v1/outreach?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/outreach",
        "per_page": 10,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/outreach

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

type   integer  optional  

Filter by outreach type. Example: 1

user_id   integer  optional  

Filter by user id. Example: 12

search   string  optional  

Filter by value, description, email, or phone. Example: prospect

date_from   string  optional  

date Filter by start date (YYYY-MM-DD). Example: 2024-01-01

date_to   string  optional  

date Filter by end date (YYYY-MM-DD). Example: 2024-12-31

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, type, value, datetime, created_at, updated_at. Example: datetime

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new outreach activity.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/outreach" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"type\": 1,
    \"value\": \"Initial contact\",
    \"email\": \"[email protected]\",
    \"phone\": \"+1 202 555 0147\",
    \"user_id\": 12,
    \"description\": \"Initial outreach via email\",
    \"datetime\": \"2024-01-10T08:00:00Z\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/outreach"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "type": 1,
    "value": "Initial contact",
    "email": "[email protected]",
    "phone": "+1 202 555 0147",
    "user_id": 12,
    "description": "Initial outreach via email",
    "datetime": "2024-01-10T08:00:00Z"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "message": "Outreach activity created successfully.",
    "data": {
        "id": 4,
        "type": 1,
        "value": "Initial contact",
        "email": "[email protected]",
        "phone": "+1 202 555 0147",
        "user_id": 12,
        "team_id": 8,
        "description": "Initial outreach via email",
        "datetime": "2024-01-10T08:00:00.000000Z",
        "created_at": "2024-01-10T08:00:00.000000Z",
        "updated_at": "2024-01-10T08:00:00.000000Z",
        "deleted_at": null
    }
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "type": [
            "The type field is required."
        ],
        "value": [
            "The value field is required."
        ],
        "datetime": [
            "The datetime field is required."
        ]
    }
}
 

Request      

POST api/v1/outreach

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

type   integer   

Outreach type. Allowed: 1,2,3,4,5. Example: 1

value   string   

Outreach value/description. Example: Initial contact

email   string  optional  

Email address. Example: [email protected]

phone   string  optional  

Phone number. Example: +1 202 555 0147

user_id   integer  optional  

Owner id for the outreach. Defaults to the authenticated user. Example: 12

description   string  optional  

Additional description. Example: Initial outreach via email

datetime   string   

Outreach date and time (ISO 8601). Example: 2024-01-10T08:00:00Z

Update an outreach activity.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/outreach/4" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"type\": 2,
    \"value\": \"Follow-up call\",
    \"email\": \"[email protected]\",
    \"phone\": \"+1 202 555 0147\",
    \"user_id\": 12,
    \"description\": \"Follow-up call made\",
    \"datetime\": \"2024-01-11T10:00:00Z\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/outreach/4"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "type": 2,
    "value": "Follow-up call",
    "email": "[email protected]",
    "phone": "+1 202 555 0147",
    "user_id": 12,
    "description": "Follow-up call made",
    "datetime": "2024-01-11T10:00:00Z"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "message": "Outreach activity updated successfully.",
    "data": {
        "id": 4,
        "type": 2,
        "value": "Follow-up call",
        "email": "[email protected]",
        "phone": "+1 202 555 0147",
        "user_id": 12,
        "team_id": 8,
        "description": "Follow-up call made",
        "datetime": "2024-01-11T10:00:00.000000Z",
        "created_at": "2024-01-10T08:00:00.000000Z",
        "updated_at": "2024-01-11T10:00:00.000000Z",
        "deleted_at": null
    }
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "type": [
            "The selected type is invalid."
        ]
    }
}
 

Request      

PUT api/v1/outreach/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Outreach id. Example: 4

Body Parameters

type   integer  optional  

Outreach type. Allowed: 1,2,3,4,5. Example: 2

value   string  optional  

Outreach value/description. Example: Follow-up call

email   string  optional  

Email address. Example: [email protected]

phone   string  optional  

Phone number. Example: +1 202 555 0147

user_id   integer  optional  

Owner id for the outreach. Example: 12

description   string  optional  

Additional description. Example: Follow-up call made

datetime   string  optional  

Outreach date and time (ISO 8601). Example: 2024-01-11T10:00:00Z

Delete an outreach activity.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/outreach/4" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/outreach/4"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/outreach/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Outreach id. Example: 4

Pay Rates

APIs for managing user pay rates over time.

Pay rates represent hourly rates assigned to users with specific start dates. Users can have multiple pay rates over time, but only one rate per date.

Display a paginated list of pay rates for a user.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/users/1/pay-rates?per_page=50&sort=started_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/users/1/pay-rates"
);

const params = {
    "per_page": "50",
    "sort": "started_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "rate": 50,
            "user_id": 1,
            "status": "current",
            "started_at": "2024-01-01T00:00:00.000000Z",
            "created_at": "2024-01-01T00:00:00.000000Z",
            "updated_at": "2024-01-01T00:00:00.000000Z"
        },
        {
            "id": 2,
            "rate": 55,
            "user_id": 1,
            "status": "future",
            "started_at": "2024-02-01T00:00:00.000000Z",
            "created_at": "2024-01-15T10:30:00.000000Z",
            "updated_at": "2024-01-15T10:30:00.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/users/1/pay-rates?page=1",
        "last": "https://example.com/api/v1/users/1/pay-rates?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/users/1/pay-rates",
        "per_page": 30,
        "to": 2,
        "total": 2
    }
}
 

Request      

GET api/v1/users/{user_id}/pay-rates

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

user_id   integer   

The ID of the user. Example: 1

user   integer   

User ID. Example: 1

Query Parameters

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, rate, started_at, created_at, updated_at. Example: started_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new pay rate.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/users/1/pay-rates" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"rate\": \"50.00\",
    \"started_at\": \"2024-01-01\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/users/1/pay-rates"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "rate": "50.00",
    "started_at": "2024-01-01"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 3,
    "rate": 50,
    "user_id": 1,
    "status": "past",
    "started_at": "2023-12-01T00:00:00.000000Z",
    "created_at": "2024-01-15T10:30:00.000000Z",
    "updated_at": "2024-01-15T10:30:00.000000Z"
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "started_at": [
            "The start date already exists for this user."
        ]
    }
}
 

Request      

POST api/v1/users/{user_id}/pay-rates

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

user_id   integer   

The ID of the user. Example: 1

user   integer   

User ID. Example: 1

Body Parameters

rate   numeric   

Hourly rate. Example: 50.00

started_at   date   

Start date of the pay rate. Example: 2024-01-01

Update a pay rate.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/users/1/pay-rates/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"rate\": \"55.00\",
    \"started_at\": \"2024-02-01\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/users/1/pay-rates/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "rate": "55.00",
    "started_at": "2024-02-01"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 1,
    "rate": 55,
    "user_id": 1,
    "status": "current",
    "started_at": "2024-01-15T00:00:00.000000Z",
    "created_at": "2024-01-01T00:00:00.000000Z",
    "updated_at": "2024-01-15T11:45:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Pay rate not found for this user"
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "started_at": [
            "The start date already exists for this user."
        ]
    }
}
 

Request      

PUT api/v1/users/{user_id}/pay-rates/{payRate_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

user_id   integer   

The ID of the user. Example: 1

payRate_id   integer   

The ID of the payRate. Example: 1

user   integer   

User ID. Example: 1

id   integer   

Pay Rate ID. Example: 1

Body Parameters

rate   numeric  optional  

Hourly rate. Example: 55.00

started_at   date  optional  

Start date of the pay rate. Example: 2024-02-01

Delete a pay rate.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/users/1/pay-rates/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/users/1/pay-rates/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Pay rate not found for this user"
}
 

Example response (422, validation_error):


{
    "message": "The given data was invalid.",
    "errors": {
        "error": [
            "Current and past pay rates cannot be deleted."
        ]
    }
}
 

Request      

DELETE api/v1/users/{user_id}/pay-rates/{payRate_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

user_id   integer   

The ID of the user. Example: 1

payRate_id   integer   

The ID of the payRate. Example: 1

user   integer   

User ID. Example: 1

id   integer   

Pay Rate ID. Example: 2

Project Rates

APIs for managing project rates.

Project rates define billing rates for projects. These endpoints let you list, create, update, and delete rates for specific projects.

Display a paginated list of project rates.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/projects/1/rates?user_id=5&currency_id=1&per_page=50&sort=started_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/1/rates"
);

const params = {
    "user_id": "5",
    "currency_id": "1",
    "per_page": "50",
    "sort": "started_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "project_id": 1,
            "user_id": 5,
            "rate": 100,
            "currency_id": 1,
            "started_at": "2024-01-01T00:00:00.000000Z",
            "created_at": "2024-01-01T00:00:00.000000Z",
            "updated_at": "2024-01-01T00:00:00.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/projects/1/rates?page=1",
        "last": "https://example.com/api/v1/projects/1/rates?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/projects/1/rates",
        "per_page": 30,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/projects/{project_id}/rates

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

project_id   integer   

The ID of the project. Example: 1

project   integer   

Project id. Example: 1

Query Parameters

user_id   integer  optional  

Filter rates by user id. Example: 5

currency_id   integer  optional  

Filter rates by currency id. Example: 1

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, rate, user_id, currency_id, started_at, created_at, updated_at. Example: started_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new project rate.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/projects/1/rates" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"rate\": \"100.00\",
    \"started_at\": \"2024-01-01\",
    \"user_id\": 5,
    \"currency_id\": 1
}"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/1/rates"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "rate": "100.00",
    "started_at": "2024-01-01",
    "user_id": 5,
    "currency_id": 1
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 1,
    "project_id": 1,
    "user_id": 5,
    "rate": 100,
    "currency_id": 1,
    "started_at": "2024-01-01T00:00:00.000000Z",
    "created_at": "2024-01-01T00:00:00.000000Z",
    "updated_at": "2024-01-01T00:00:00.000000Z"
}
 

Example response (422, validation_error):


{
    "message": "The Start date already exists"
}
 

Request      

POST api/v1/projects/{project_id}/rates

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

project_id   integer   

The ID of the project. Example: 1

project   integer   

Project id. Example: 1

Body Parameters

rate   numeric   

Hourly rate. Example: 100.00

started_at   string   

Start date for the rate (YYYY-MM-DD). Example: 2024-01-01

user_id   integer  optional  

User id for the rate (nullable). Example: 5

currency_id   integer   

Currency id for the rate. Example: 1

Update a project rate.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/projects/1/rates/119" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"rate\": \"120.00\",
    \"started_at\": \"2024-02-01\",
    \"user_id\": 5,
    \"currency_id\": 1
}"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/1/rates/119"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "rate": "120.00",
    "started_at": "2024-02-01",
    "user_id": 5,
    "currency_id": 1
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 1,
    "project_id": 1,
    "user_id": 5,
    "rate": 120,
    "currency_id": 1,
    "started_at": "2024-02-01T00:00:00.000000Z",
    "created_at": "2024-01-01T00:00:00.000000Z",
    "updated_at": "2024-01-15T10:30:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Project rate not found for this project"
}
 

Example response (422, validation_error):


{
    "message": "The Start date already exists"
}
 

Request      

PUT api/v1/projects/{project_id}/rates/{projectRate_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

project_id   integer   

The ID of the project. Example: 1

projectRate_id   integer   

The ID of the projectRate. Example: 119

project   integer   

Project id. Example: 1

projectRate   integer   

Project rate id. Example: 1

Body Parameters

rate   numeric  optional  

Hourly rate. Example: 120.00

started_at   string  optional  

Start date for the rate (YYYY-MM-DD). Example: 2024-02-01

user_id   integer  optional  

User id for the rate (nullable). Example: 5

currency_id   integer  optional  

Currency id for the rate. Example: 1

Delete a project rate.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/projects/1/rates/119" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/1/rates/119"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Project rate not found for this project"
}
 

Example response (422, validation_error):


{
    "message": "Current and past project rate cannot be deleted"
}
 

Request      

DELETE api/v1/projects/{project_id}/rates/{projectRate_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

project_id   integer   

The ID of the project. Example: 1

projectRate_id   integer   

The ID of the projectRate. Example: 119

project   integer   

Project id. Example: 1

projectRate   integer   

Project rate id. Example: 1

Projects

APIs for managing projects.

Projects represent client initiatives. These endpoints let you list, create, update, and delete projects that belong to your team.

Display a paginated list of projects.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/projects?search=onboarding&client_id=4&user_id=12&billable=1&per_page=50&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/projects"
);

const params = {
    "search": "onboarding",
    "client_id": "4",
    "user_id": "12",
    "billable": "1",
    "per_page": "50",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 3,
            "name": "Client onboarding",
            "description": "Kick-off project for ACME Inc.",
            "client_id": 4,
            "user_id": 12,
            "team_id": 8,
            "billable": true,
            "created_at": "2025-01-10T08:00:00.000000Z",
            "updated_at": "2025-01-10T08:00:00.000000Z",
            "deleted_at": null
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/projects?page=1",
        "last": "https://example.com/api/v1/projects?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/projects",
        "per_page": 30,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/projects

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Filter projects by partial match in the project name. Example: onboarding

client_id   integer  optional  

Filter projects by client id. Example: 4

user_id   integer  optional  

Filter projects by owner id. Example: 12

billable   boolean  optional  

Filter by billable flag. Example: true

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, name, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new project.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/projects" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Client onboarding\",
    \"description\": \"Kick-off project for ACME Inc.\",
    \"client_id\": 4,
    \"billable\": true,
    \"user_id\": 12
}"
const url = new URL(
    "https://app.corcava.com/api/v1/projects"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Client onboarding",
    "description": "Kick-off project for ACME Inc.",
    "client_id": 4,
    "billable": true,
    "user_id": 12
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 3,
    "name": "Client onboarding",
    "description": "Kick-off project for ACME Inc.",
    "client_id": 4,
    "user_id": 12,
    "team_id": 8,
    "billable": true,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z",
    "deleted_at": null
}
 

Example response (422, validation_error):


{
    "message": "Client not found"
}
 

Request      

POST api/v1/projects

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

Project name. Example: Client onboarding

description   string  optional  

Project description. Example: Kick-off project for ACME Inc.

client_id   integer   

Client id that owns the project. Example: 4

billable   boolean  optional  

Whether time tracked on the project is billable. Example: true

user_id   integer  optional  

Owner id for the project. Defaults to the authenticated user. Example: 12

team_id   string  optional  

Display a single project.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/projects/3" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/3"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 3,
    "name": "Client onboarding",
    "description": "Kick-off project for ACME Inc.",
    "client_id": 4,
    "user_id": 12,
    "team_id": 8,
    "billable": true,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z",
    "deleted_at": null
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/projects/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Project id. Example: 3

Update a project.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/projects/3" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Client onboarding\",
    \"description\": \"Kick-off project for ACME Inc.\",
    \"client_id\": 4,
    \"billable\": true,
    \"user_id\": 12
}"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/3"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Client onboarding",
    "description": "Kick-off project for ACME Inc.",
    "client_id": 4,
    "billable": true,
    "user_id": 12
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 3,
    "name": "Client onboarding",
    "description": "Kick-off project for ACME Inc.",
    "client_id": 4,
    "user_id": 12,
    "team_id": 8,
    "billable": true,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T10:30:00.000000Z",
    "deleted_at": null
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/projects/{id}

PATCH api/v1/projects/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Project id. Example: 3

Body Parameters

name   string  optional  

Project name. Example: Client onboarding

description   string  optional  

Project description. Example: Kick-off project for ACME Inc.

client_id   integer  optional  

Client id that owns the project. Example: 4

billable   boolean  optional  

Whether time tracked on the project is billable. Example: true

user_id   integer  optional  

Owner id for the project. Example: 12

team_id   string  optional  

Delete a project.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/projects/3" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/projects/3"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/projects/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Project id. Example: 3

Reports

APIs for querying time tracking reports.

These endpoints let you query aggregated time tracking data with various filters and grouping options. Every request must be authenticated via an active Public API key or Bearer token.

Query time tracking reports.

requires authentication

Returns time tracking data grouped by member, project, client, date, or task. Supports filtering by date range, members, projects, and clients.

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/reports?start=2025-01-01&end=2025-01-31&groupBy=project&members[]=1&members[]=2&members[]=3&projects[]=10&projects[]=20&clients[]=5&clients[]=6&summary_only=1&fields=user_name%2Cproject_name%2Cbilled%2Cspent" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/reports"
);

const params = {
    "start": "2025-01-01",
    "end": "2025-01-31",
    "groupBy": "project",
    "members[0]": "1",
    "members[1]": "2",
    "members[2]": "3",
    "projects[0]": "10",
    "projects[1]": "20",
    "clients[0]": "5",
    "clients[1]": "6",
    "summary_only": "1",
    "fields": "user_name,project_name,billed,spent",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "status": "success",
    "totals": {
        "total_time": "45h 30m",
        "total_spent": 2500,
        "total_billed": 4500,
        "currencyGroups": {},
        "baseCurrencySums": {}
    },
    "filters": {
        "teamId": 1,
        "startedDate": "2025-01-01 00:00:00",
        "endDate": "2025-01-31 23:59:59",
        "projects": null,
        "members": null,
        "clients": null,
        "groupBy": "project"
    },
    "summary": {
        "1": {
            "group_id": 1,
            "group_name": "Project Alpha",
            "total_spent": 1200,
            "total_billed": 2400,
            "profit": 1200,
            "profit_margin": 50,
            "total_time": "24h 00m",
            "total_seconds": 86400
        }
    }
}
 

Example response (401, unauthenticated):


{
    "message": "Authorization required"
}
 

Request      

GET api/v1/reports

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

start   string  optional  

date Start date for the report period. Defaults to start of current week. Example: 2025-01-01

end   string  optional  

date End date for the report period. Defaults to end of current week. Example: 2025-01-31

groupBy   string  optional  

How to group results. Allowed: member, project, date, client, task. Example: project

members   string[]  optional  

Filter by member IDs.

projects   string[]  optional  

Filter by project IDs.

clients   string[]  optional  

Filter by client IDs.

summary_only   boolean  optional  

If true, return only aggregated totals per group (faster for profitability queries). Example: true

fields   string  optional  

Comma-separated list of fields to return. Example: user_name,project_name,billed,spent

Screenshots

APIs for managing time tracking screenshots.

These endpoints let you list screenshots captured during time tracking sessions. Screenshots are organized by user, project, and date.

Display a paginated list of screenshots.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/screenshots?project_id=5&user_id=12&date=2024-01-15&date_from=2024-01-01&date_to=2024-01-31&per_page=50&sort=started_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/screenshots"
);

const params = {
    "project_id": "5",
    "user_id": "12",
    "date": "2024-01-15",
    "date_from": "2024-01-01",
    "date_to": "2024-01-31",
    "per_page": "50",
    "sort": "started_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 123,
            "project_id": 5,
            "user_id": 12,
            "path": "screenshots/2024/01/15/abc123.jpg",
            "signed_url": "https://storage.example.com/screenshots/2024/01/15/abc123.jpg?signature=abc123",
            "taken_at": "2024-01-15T10:30:00.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/screenshots?page=1",
        "last": "https://example.com/api/v1/screenshots?page=3",
        "prev": null,
        "next": "https://example.com/api/v1/screenshots?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "path": "https://example.com/api/v1/screenshots",
        "per_page": 30,
        "to": 30,
        "total": 85
    }
}
 

Request      

GET api/v1/screenshots

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

project_id   integer  optional  

Filter screenshots by project ID. Example: 5

user_id   integer  optional  

Filter screenshots by user ID. Only superadmins and organization managers can view other users' screenshots. Defaults to authenticated user's ID. Example: 12

date   string  optional  

Filter screenshots by specific date (YYYY-MM-DD format). Example: 2024-01-15

date_from   string  optional  

Filter screenshots by date range start (YYYY-MM-DD format). Example: 2024-01-01

date_to   string  optional  

Filter screenshots by date range end (YYYY-MM-DD format). Requires date_from parameter. Example: 2024-01-31

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, started_at, user_id, project_id. Example: started_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Tags

Team-scoped tags that can be attached to contacts, projects, tasks, and other resources.

GET api/v1/tags

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/tags" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tags"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: X-Inertia
access-control-allow-origin: *
set-cookie: XSRF-TOKEN=eyJpdiI6IkNNcW1EVm9CRWlWMTd2OVQyb1gzRnc9PSIsInZhbHVlIjoiclQyS3VrSzNENXdrZmU4ZE5pOS9ZbWV0bzBKZ0ZteXNISTIxY1NpTElvUitvSWkxRk9XeTFSZ3RCRW90WHk1eUVGMG1yUUFMVDhRSFp6c0lIN0tQMm9zWDMxRzZDZFp0b1B4ejRORG1kelJzMy9hVUk5L0hEY01veUJOUVFCZ1giLCJtYWMiOiIwMzJiZDBjY2Y1MDljNDIwYjE5ZGQ5ODIxY2IyOWEwMjM1YTRkNGFhMGIwNWFjYmU0NjQyNGZmYmY5ZWUyOGIxIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; samesite=lax; corcava_session=eyJpdiI6IlJIQS9KUVBvMXlvMWlsY1hPaUV6dXc9PSIsInZhbHVlIjoiS1RDZkxzYjhqT1lZTTVsMFR1aUdEUENCejh2VUJ1T1NyaEp4eWJMVHlDR204TXNsQThjNW9JbWcyTEJqdzhicy9NRVNMMGZHcFVCTFUwT0JWTzBkRmh0Vm1saXdtbW9nVjhzeE5ndUlqSFZzME5mNFNpYVAyQXhMVTQyWmlCc2UiLCJtYWMiOiI0NWI1OTU0ZmJlYzBlOWM5Y2U4Mzk0ZDhlMWQ5NGFiOTMzYTdhM2RlODEzNzEzY2UwNjdkZWRlYmRlN2JhN2JlIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; httponly; samesite=lax
 

{
    "message": "Authorization required"
}
 

Request      

GET api/v1/tags

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

POST api/v1/tags

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/tags" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"b\",
    \"color\": \"ngzmiyvdljnikhwa\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tags"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "b",
    "color": "ngzmiyvdljnikhwa"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/v1/tags

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

Must not be greater than 100 characters. Example: b

color   string  optional  

Must not be greater than 20 characters. Example: ngzmiyvdljnikhwa

GET api/v1/tags/{tag_id}

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/tags/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tags/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: X-Inertia
access-control-allow-origin: *
set-cookie: XSRF-TOKEN=eyJpdiI6IkZFOEE2WkZGV3k1MGVlZ0xOQ1ptbVE9PSIsInZhbHVlIjoiODFQY1plZEVYT3ZzZG1idXU2SnJVbnQzWXQyS2F5UUw4WGJFdGprM2htOHZXclpwdUFnQzZoRDJ5a3QxRUt1UWJkdUU5dkE4UEY1dWFPdURxMjAySm9Femt5VVhLYnRTT3RLd255UmdqZlE2azNGR1ptaWpUMWhVbm1Jb1EzTHciLCJtYWMiOiI1OGMzNzA1N2NiMTZkODE5YTdmZWVhNDU4YjA1OGJmMmRmNDExYWQ2NDQ4ODhkZWM2Y2MzMTQ5NTA3YmUxYjBhIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; samesite=lax; corcava_session=eyJpdiI6IjZjRlBmbldpck5kdXR2bExaU21URWc9PSIsInZhbHVlIjoiVnFEVTRGa1k0Mm1jRWhQOXNjMTg1emc0bmY5YjhtTkhuSXduV3BrVjRHeE9wWW82ODY3UUtDeGwwOUt5MnZOOForRUpoR1pkZ3B0TFd0WTRoKzBDTmlFZjRiKzdEVlB6ZENZVWU0bEQ3OEg2ais0TkJWSmsyV1FKWlRzRlNvZG4iLCJtYWMiOiIwMTk1MDYxNjA2ZGFiYTU0Y2NhNWNjMmY4ODFlYzc1MzQwNTU0ZGEzNzE2ZWExODliOWY2Y2VmMTAxOWYzY2QyIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:23 GMT; Max-Age=172800; path=/; secure; httponly; samesite=lax
 

{
    "message": "Authorization required"
}
 

Request      

GET api/v1/tags/{tag_id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

tag_id   integer   

The ID of the tag. Example: 1

PUT api/v1/tags/{tag_id}

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/tags/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"b\",
    \"color\": \"ngzmiyvdljnikhwa\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tags/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "b",
    "color": "ngzmiyvdljnikhwa"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

PUT api/v1/tags/{tag_id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

tag_id   integer   

The ID of the tag. Example: 1

Body Parameters

name   string   

Must not be greater than 100 characters. Example: b

color   string  optional  

Must not be greater than 20 characters. Example: ngzmiyvdljnikhwa

DELETE api/v1/tags/{tag_id}

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/tags/1" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tags/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Request      

DELETE api/v1/tags/{tag_id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

tag_id   integer   

The ID of the tag. Example: 1

PUT api/v1/taggables/{type}/{id}/tags

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/taggables/architecto/architecto/tags" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"tag_ids\": [
        16
    ],
    \"tag_names\": [
        \"n\"
    ]
}"
const url = new URL(
    "https://app.corcava.com/api/v1/taggables/architecto/architecto/tags"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "tag_ids": [
        16
    ],
    "tag_names": [
        "n"
    ]
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

PUT api/v1/taggables/{type}/{id}/tags

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

type   string   

Example: architecto

id   string   

The ID of the {type}. Example: architecto

Body Parameters

tag_ids   integer[]  optional  

Must be at least 1.

tag_names   string[]  optional  

Must not be greater than 100 characters.

Task Comments

APIs for managing comments on tasks.

Comments are stored as TaskEvent records with type='comment'. These endpoints let you list, add, update, and delete comments on tasks. Every request must be authenticated via an active Public API key.

List comments on a task.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/tasks/42/comments?per_page=50" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/42/comments"
);

const params = {
    "per_page": "50",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "task_id": 42,
            "user_id": 5,
            "user_name": "John Doe",
            "text": "Blocked waiting on design review",
            "created_at": "2025-01-11T10:15:00.000000Z",
            "updated_at": "2025-01-11T10:15:00.000000Z"
        }
    ],
    "meta": {
        "current_page": 1,
        "total": 1
    }
}
 

Example response (404, not_found):


{
    "message": "Task not found"
}
 

Request      

GET api/v1/tasks/{task}/comments

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

task   integer   

Task ID. Example: 42

Query Parameters

per_page   integer  optional  

The number of results per page. Maximum: 100. Example: 50

Add a comment to a task.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/tasks/42/comments" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"text\": \"Blocked waiting on design review\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/42/comments"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "text": "Blocked waiting on design review"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 15,
    "task_id": 42,
    "user_id": 5,
    "user_name": "John Doe",
    "text": "Blocked waiting on design review",
    "created_at": "2025-01-11T10:15:00.000000Z",
    "updated_at": "2025-01-11T10:15:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Task not found"
}
 

Example response (422, validation_error):


{
    "message": "The text field is required."
}
 

Request      

POST api/v1/tasks/{task}/comments

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

task   integer   

Task ID. Example: 42

Body Parameters

text   string   

The comment text. Example: Blocked waiting on design review

Get a single comment.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/tasks/42/comments/15" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/42/comments/15"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 15,
    "task_id": 42,
    "user_id": 5,
    "user_name": "John Doe",
    "text": "Blocked waiting on design review",
    "created_at": "2025-01-11T10:15:00.000000Z",
    "updated_at": "2025-01-11T10:15:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Comment not found"
}
 

Request      

GET api/v1/tasks/{task}/comments/{comment}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

task   integer   

Task ID. Example: 42

comment   integer   

Comment ID. Example: 15

Update a comment.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/tasks/42/comments/15" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"text\": \"Updated: Ready for QA\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/42/comments/15"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "text": "Updated: Ready for QA"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 15,
    "task_id": 42,
    "user_id": 5,
    "user_name": "John Doe",
    "text": "Updated: Ready for QA",
    "created_at": "2025-01-11T10:15:00.000000Z",
    "updated_at": "2025-01-11T16:30:00.000000Z"
}
 

Example response (403, forbidden):


{
    "message": "You can only edit your own comments"
}
 

Example response (404, not_found):


{
    "message": "Comment not found"
}
 

Request      

PUT api/v1/tasks/{task}/comments/{comment}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

task   integer   

Task ID. Example: 42

comment   integer   

Comment ID. Example: 15

Body Parameters

text   string   

The updated comment text. Example: Updated: Ready for QA

Delete a comment.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/tasks/42/comments/15" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/42/comments/15"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (403, forbidden):


{
    "message": "You can only delete your own comments"
}
 

Example response (404, not_found):


{
    "message": "Comment not found"
}
 

Request      

DELETE api/v1/tasks/{task}/comments/{comment}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

task   integer   

Task ID. Example: 42

comment   integer   

Comment ID. Example: 15

Task Events

APIs for managing task events (comments, system events).

Task events represent activity history of a task, such as user comments or system-generated changes.

Display a paginated list of task events.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/tasks/8/events?type=comment&user_id=12&per_page=30&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/8/events"
);

const params = {
    "type": "comment",
    "user_id": "12",
    "per_page": "30",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 101,
            "task_id": 15,
            "user_id": 12,
            "type": "comment",
            "text": "Looks good to me",
            "created_at": "2025-01-15T10:30:00.000000Z",
            "user": {
                "id": 12,
                "name": "Alex Johnson"
            }
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/tasks/15/events?page=1",
        "last": "https://example.com/api/v1/tasks/15/events?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/tasks/15/events",
        "per_page": 30,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/tasks/{task_id}/events

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

task_id   integer   

The ID of the task. Example: 8

task   integer   

Task id. Example: 15

Query Parameters

type   string  optional  

Filter events by type. Example: comment

user_id   integer  optional  

Filter events by author id. Example: 12

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 30

sort   string  optional  

Column used for sorting. Allowed: id, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new task event (comment).

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/tasks/8/events" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"text\": \"Please fix the validation logic.\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/8/events"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "text": "Please fix the validation logic."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 102,
    "task_id": 15,
    "user_id": 12,
    "type": "comment",
    "text": "Please fix the validation logic.",
    "created_at": "2025-01-15T11:00:00.000000Z",
    "user": {
        "id": 12,
        "name": "Alex Johnson"
    }
}
 

Request      

POST api/v1/tasks/{task_id}/events

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

task_id   integer   

The ID of the task. Example: 8

task   integer   

Task id. Example: 15

Body Parameters

text   string   

Comment text. Example: Please fix the validation logic.

Delete a task event.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/task-events/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/task-events/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (403, forbidden):


{
    "message": "This action is unauthorized."
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/task-events/{taskEvent_id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

taskEvent_id   integer   

The ID of the taskEvent. Example: 1

taskEvent   integer   

Task event id. Example: 102

Task Labels

APIs for managing task labels.

Task labels allow you to categorize and organize tasks within a project board. These endpoints let you list board labels and attach/detach labels to specific tasks.

Display a paginated list of board labels.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/boards/1/labels?per_page=30" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/boards/1/labels"
);

const params = {
    "per_page": "30",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "title": "Bug",
            "color": "#FF0000",
            "board_id": 5
        },
        {
            "id": 2,
            "title": "Feature",
            "color": "#00FF00",
            "board_id": 5
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/boards/5/labels?page=1",
        "last": "https://example.com/api/v1/boards/5/labels?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/boards/5/labels",
        "per_page": 30,
        "to": 2,
        "total": 2
    }
}
 

Request      

GET api/v1/boards/{board_id}/labels

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

board_id   integer   

The ID of the board. Example: 1

board   integer   

Board ID. Example: 5

Query Parameters

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 30

Attach a label to a task.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/tasks/8/labels" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"label_id\": 1
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/8/labels"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "label_id": 1
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 123,
    "task_id": 42,
    "label_id": 1,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:00:00.000000Z"
}
 

Example response (422, validation_error):


{
    "message": "The label id field is required.",
    "errors": {
        "label_id": [
            "The label id field is required."
        ]
    }
}
 

Request      

POST api/v1/tasks/{task_id}/labels

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

task_id   integer   

The ID of the task. Example: 8

task   integer   

Task ID. Example: 42

Body Parameters

label_id   integer   

Label ID to attach to the task. Example: 1

Update a task label.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/tasks/8/labels/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"label_id\": 2
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/8/labels/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "label_id": 2
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 123,
    "task_id": 42,
    "label_id": 2,
    "created_at": "2025-01-10T08:00:00.000000Z",
    "updated_at": "2025-01-10T08:30:00.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Label not found on task"
}
 

Example response (422, validation_error):


{
    "message": "The label id field is required.",
    "errors": {
        "label_id": [
            "The label id field is required."
        ]
    }
}
 

Request      

PUT api/v1/tasks/{task_id}/labels/{label}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

task_id   integer   

The ID of the task. Example: 8

label   integer   

Current label ID attached to the task. Example: 1

task   integer   

Task ID. Example: 42

Body Parameters

label_id   integer   

New label ID to replace the current one. Example: 2

Detach a label from a task.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/tasks/8/labels/1" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/8/labels/1"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Label not found on task"
}
 

Request      

DELETE api/v1/tasks/{task_id}/labels/{label}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

task_id   integer   

The ID of the task. Example: 8

label   integer   

Label ID to detach from the task. Example: 1

task   integer   

Task ID. Example: 42

Tasks

APIs for managing project tasks.

These endpoints let you list, create, update, and delete tasks that belong to your team. Every request must be authenticated via an active Public API key.

Display a paginated list of tasks for the authenticated team.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/tasks?search=onboarding&project_id=12&board_id=7&column_id=20&assigned_to_me=1&per_page=50&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks"
);

const params = {
    "search": "onboarding",
    "project_id": "12",
    "board_id": "7",
    "column_id": "20",
    "assigned_to_me": "1",
    "per_page": "50",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 1,
            "name": "Follow up call",
            "description": "Call the client back with the pricing update.",
            "slug": "follow-up-call",
            "team_id": 8,
            "project_id": 3,
            "project_board_id": 5,
            "column_id": 9,
            "contact_id": 21,
            "company_id": null,
            "outreach_id": null,
            "estimate_time": null,
            "date_from": "2025-01-10",
            "date_to": null,
            "closed_at": null,
            "amount": "0.00",
            "order": 2,
            "created_at": "2025-01-11T10:15:00.000000Z",
            "updated_at": "2025-01-11T10:15:00.000000Z",
            "deleted_at": null
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/tasks?page=1",
        "last": "https://example.com/api/v1/tasks?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/tasks",
        "per_page": 30,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/tasks

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Filter tasks by partial match in the task name. Example: onboarding

project_id   integer  optional  

Filter tasks by related project id. Example: 12

board_id   integer  optional  

Filter tasks by project board id. Example: 7

column_id   integer  optional  

Filter tasks by column id. Example: 20

assigned_to_me   boolean  optional  

When true (e.g. 1 or "true"), return only tasks assigned to the authenticated user (via task_users). When omitted or false, no assignment filter is applied. Requires authentication. Example: true

per_page   integer  optional  

The number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, name, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Create a new task.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/tasks" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Follow up call\",
    \"description\": \"Call the client back with the pricing update.\",
    \"estimate_time\": 3.5,
    \"date_from\": \"2025-01-10\",
    \"date_to\": \"2025-01-12\",
    \"closed_at\": \"2026-09-15T03:18:21\",
    \"outreach_id\": 16,
    \"company_id\": 16,
    \"project_id\": 3,
    \"contact_id\": 21,
    \"column_id\": 9,
    \"order\": 5,
    \"amount\": 2500,
    \"slug\": \"m\",
    \"user_ids\": [
        1,
        2,
        3
    ],
    \"project_ref\": {
        \"id\": 16,
        \"name\": \"n\"
    },
    \"tag_names\": [
        \"g\"
    ],
    \"add_tag_names\": [
        \"z\"
    ],
    \"remove_tag_names\": [
        \"m\"
    ],
    \"create_missing_tags\": true
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Follow up call",
    "description": "Call the client back with the pricing update.",
    "estimate_time": 3.5,
    "date_from": "2025-01-10",
    "date_to": "2025-01-12",
    "closed_at": "2026-09-15T03:18:21",
    "outreach_id": 16,
    "company_id": 16,
    "project_id": 3,
    "contact_id": 21,
    "column_id": 9,
    "order": 5,
    "amount": 2500,
    "slug": "m",
    "user_ids": [
        1,
        2,
        3
    ],
    "project_ref": {
        "id": 16,
        "name": "n"
    },
    "tag_names": [
        "g"
    ],
    "add_tag_names": [
        "z"
    ],
    "remove_tag_names": [
        "m"
    ],
    "create_missing_tags": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 42,
    "name": "Follow up call",
    "description": "Call the client back with the pricing update.",
    "slug": "follow-up-call",
    "team_id": 8,
    "project_id": 3,
    "project_board_id": 5,
    "column_id": 9,
    "contact_id": 21,
    "company_id": null,
    "outreach_id": null,
    "estimate_time": null,
    "date_from": "2025-01-10",
    "date_to": null,
    "closed_at": null,
    "amount": "0.00",
    "order": 2,
    "created_at": "2025-01-11T10:15:00.000000Z",
    "updated_at": "2025-01-11T10:15:00.000000Z",
    "deleted_at": null
}
 

Example response (422, validation_error):


{
    "message": "Column not found"
}
 

Request      

POST api/v1/tasks

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

Task title. Example: Follow up call

description   string  optional  

Task description. Example: Call the client back with the pricing update.

estimate_time   number  optional  

Estimated effort in hours. Example: 3.5

date_from   date  optional  

Start date of the task. Example: 2025-01-10

date_to   date  optional  

Due date of the task. Example: 2025-01-12

closed_at   string  optional  

Must be a valid date. Example: 2026-09-15T03:18:21

outreach_id   integer  optional  

Example: 16

company_id   integer  optional  

Example: 16

project_id   integer  optional  

The related project id. Must belong to your team. Example: 3

project_board_id   string  optional  
contact_id   integer  optional  

The related contact id. Must belong to your team. Example: 21

column_id   integer   

Column id where the task should be created. Example: 9

order   integer  optional  

Custom position inside the column. Example: 5

amount   number  optional  

Monetary amount associated with the task. Example: 2500

slug   string  optional  

Must not be greater than 255 characters. Example: m

user_ids   integer[]  optional  

Array of user IDs to assign to this task.

project_ref   object  optional  
id   integer  optional  

Example: 16

name   string  optional  

Must not be greater than 255 characters. Example: n

tag_names   string[]  optional  

Must not be greater than 255 characters.

add_tag_names   string[]  optional  

Must not be greater than 255 characters.

remove_tag_names   string[]  optional  

Must not be greater than 255 characters.

create_missing_tags   boolean  optional  

Example: true

Display a single task.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/tasks/42" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/42"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 42,
    "name": "Follow up call",
    "description": "Call the client back with the pricing update.",
    "slug": "follow-up-call",
    "team_id": 8,
    "project_id": 3,
    "project_board_id": 5,
    "column_id": 9,
    "contact_id": 21,
    "company_id": null,
    "outreach_id": null,
    "estimate_time": null,
    "date_from": "2025-01-10",
    "date_to": null,
    "closed_at": null,
    "amount": "0.00",
    "order": 2,
    "created_at": "2025-01-11T10:15:00.000000Z",
    "updated_at": "2025-01-11T10:15:00.000000Z",
    "deleted_at": null
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/tasks/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Task id. Example: 42

Update a task.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/tasks/42" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"Follow up call\",
    \"description\": \"Call the client with the new quote.\",
    \"estimate_time\": 4,
    \"date_from\": \"2025-01-10\",
    \"date_to\": \"2025-01-12\",
    \"closed_at\": \"2026-09-15T03:18:21\",
    \"outreach_id\": 16,
    \"company_id\": 16,
    \"project_id\": 3,
    \"contact_id\": 21,
    \"column_id\": 9,
    \"order\": 5,
    \"amount\": 2500,
    \"slug\": \"m\",
    \"user_ids\": [
        1,
        2,
        3
    ],
    \"tag_names\": [
        \"g\"
    ],
    \"add_tag_names\": [
        \"z\"
    ],
    \"remove_tag_names\": [
        \"m\"
    ],
    \"create_missing_tags\": true
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/42"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Follow up call",
    "description": "Call the client with the new quote.",
    "estimate_time": 4,
    "date_from": "2025-01-10",
    "date_to": "2025-01-12",
    "closed_at": "2026-09-15T03:18:21",
    "outreach_id": 16,
    "company_id": 16,
    "project_id": 3,
    "contact_id": 21,
    "column_id": 9,
    "order": 5,
    "amount": 2500,
    "slug": "m",
    "user_ids": [
        1,
        2,
        3
    ],
    "tag_names": [
        "g"
    ],
    "add_tag_names": [
        "z"
    ],
    "remove_tag_names": [
        "m"
    ],
    "create_missing_tags": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 42,
    "name": "Follow up call",
    "description": "Call the client with the new quote.",
    "slug": "follow-up-call",
    "team_id": 8,
    "project_id": 3,
    "project_board_id": 5,
    "column_id": 9,
    "contact_id": 21,
    "company_id": null,
    "outreach_id": null,
    "estimate_time": null,
    "date_from": "2025-01-10",
    "date_to": null,
    "closed_at": null,
    "amount": "0.00",
    "order": 4,
    "created_at": "2025-01-11T10:15:00.000000Z",
    "updated_at": "2025-01-11T16:20:00.000000Z",
    "deleted_at": null
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/tasks/{id}

PATCH api/v1/tasks/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Task id. Example: 42

Body Parameters

name   string  optional  

Task title. Example: Follow up call

description   string  optional  

Task description. Example: Call the client with the new quote.

estimate_time   number  optional  

Estimated effort in hours. Example: 4

date_from   date  optional  

Start date. Example: 2025-01-10

date_to   date  optional  

Due date. Example: 2025-01-12

closed_at   string  optional  

Must be a valid date. Example: 2026-09-15T03:18:21

outreach_id   integer  optional  

Example: 16

company_id   integer  optional  

Example: 16

project_id   integer  optional  

The related project id. Must belong to your team. Example: 3

project_board_id   string  optional  
contact_id   integer  optional  

The related contact id. Example: 21

column_id   integer  optional  

Column id where the task should live. Example: 9

order   integer  optional  

Custom position inside the column. Example: 5

amount   number  optional  

Monetary amount. Example: 2500

slug   string  optional  

Must not be greater than 255 characters. Example: m

user_ids   integer[]  optional  

Array of user IDs to assign to this task. Replaces existing assignments.

project_ref   string  optional  
id   integer  optional  

Example: 16

name   string  optional  

Must not be greater than 255 characters. Example: n

tag_names   string[]  optional  

Must not be greater than 255 characters.

add_tag_names   string[]  optional  

Must not be greater than 255 characters.

remove_tag_names   string[]  optional  

Must not be greater than 255 characters.

create_missing_tags   boolean  optional  

Example: true

Delete a task.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/tasks/42" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tasks/42"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/tasks/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Task id. Example: 42

Team Invoices

APIs for managing team invoices.

Invoices represent bills issued to clients. These endpoints let you list, view, close, and reopen invoices that belong to your team.

Display a paginated list of team invoices.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/team-invoices?search=INV-2023-001&user_id=12&status=sent&date_from=2023-01-01&date_to=2023-12-31&per_page=50&sort=created_at&direction=desc" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/team-invoices"
);

const params = {
    "search": "INV-2023-001",
    "user_id": "12",
    "status": "sent",
    "date_from": "2023-01-01",
    "date_to": "2023-12-31",
    "per_page": "50",
    "sort": "created_at",
    "direction": "desc",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 45,
            "number": "INV-2023-001",
            "hash": "abc123def456",
            "status": "sent",
            "amount": 1500,
            "currency_id": 1,
            "issue_date": "2023-01-15",
            "due_date": "2023-02-15",
            "client_id": 8,
            "user_id": 12,
            "team_id": 5,
            "created_at": "2023-01-15T10:00:00.000000Z",
            "updated_at": "2023-01-15T10:00:00.000000Z",
            "currency": {
                "id": 1,
                "code": "USD",
                "name": "US Dollar"
            },
            "user": {
                "id": 12,
                "name": "John Doe",
                "email": "[email protected]"
            },
            "items": [
                {
                    "id": 1,
                    "description": "Website Development",
                    "quantity": 10,
                    "unit_price": 150,
                    "total": 1500
                }
            ]
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/team-invoices?page=1",
        "last": "https://example.com/api/v1/team-invoices?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://example.com/api/v1/team-invoices",
        "per_page": 50,
        "to": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/team-invoices

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Filter invoices by invoice number. Example: INV-2023-001

user_id   integer  optional  

Filter invoices by user (creator) id. Example: 12

status   string  optional  

Filter by invoice status. Example: sent

date_from   string  optional  

date Filter invoices created from this date (YYYY-MM-DD). Example: 2023-01-01

date_to   string  optional  

date Filter invoices created until this date (YYYY-MM-DD). Example: 2023-12-31

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

sort   string  optional  

Column used for sorting. Allowed: id, number, amount, status, issue_date, due_date, created_at, updated_at. Example: created_at

direction   string  optional  

Sort direction. Allowed: asc, desc. Example: desc

Display a single team invoice.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/team-invoices/abc123def456" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/team-invoices/abc123def456"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 45,
    "number": "INV-2023-001",
    "hash": "abc123def456",
    "status": "sent",
    "amount": 1500,
    "currency_id": 1,
    "issue_date": "2023-01-15",
    "due_date": "2023-02-15",
    "client_id": 8,
    "user_id": 12,
    "team_id": 5,
    "created_at": "2023-01-15T10:00:00.000000Z",
    "updated_at": "2023-01-15T10:00:00.000000Z",
    "total_paid": 750,
    "balance_due": 750,
    "currency": {
        "id": 1,
        "code": "USD",
        "name": "US Dollar"
    },
    "user": {
        "id": 12,
        "name": "John Doe",
        "email": "[email protected]"
    },
    "items": [
        {
            "id": 1,
            "description": "Website Development",
            "quantity": 10,
            "unit_price": 150,
            "total": 1500
        }
    ],
    "invoice_payments": [
        {
            "id": 3,
            "amount_paid": 750,
            "payment_date": "2023-01-20",
            "payment_method": "credit_card"
        }
    ]
}
 

Example response (404, not_found):


{
    "message": "Team invoice not found"
}
 

Request      

GET api/v1/team-invoices/{hash}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

hash   string   

Invoice hash identifier. Example: abc123def456

Close an invoice.

requires authentication

Marks a sent invoice as closed. Only invoices with "sent" status can be closed.

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/team-invoices/abc123def456/close" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/team-invoices/abc123def456/close"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "PUT",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "message": "Team invoice closed successfully"
}
 

Example response (403, unauthorized):


{
    "message": "This action is unauthorized."
}
 

Example response (404, not_found):


{
    "message": "Team invoice not found"
}
 

Example response (422, invalid_status):


{
    "message": "Only sent invoices can be closed."
}
 

Request      

PUT api/v1/team-invoices/{hash}/close

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

hash   string   

Invoice hash identifier. Example: abc123def456

Reopen an invoice.

requires authentication

Reopens a closed invoice, changing its status back to sent. Only invoices with "closed" status can be reopened.

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/team-invoices/abc123def456/reopen" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/team-invoices/abc123def456/reopen"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "PUT",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "message": "Team invoice reopened successfully"
}
 

Example response (403, unauthorized):


{
    "message": "This action is unauthorized."
}
 

Example response (404, not_found):


{
    "message": "Team invoice not found"
}
 

Example response (422, invalid_status):


{
    "message": "Only closed invoices can be reopened."
}
 

Request      

PUT api/v1/team-invoices/{hash}/reopen

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

hash   string   

Invoice hash identifier. Example: abc123def456

Team Members

APIs for listing team members (users).

Team members are users who belong to your team. Use these endpoints to search and list members. This endpoint supports fuzzy search - typos, partial names, and accents are handled automatically.

List team members with optional fuzzy search.

requires authentication

Returns team members matching the search query. Supports fuzzy matching:

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/users?search=alex&per_page=50" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/users"
);

const params = {
    "search": "alex",
    "per_page": "50",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 12,
            "name": "Alexander Romankó",
            "email": "[email protected]",
            "profile_photo_url": "https://example.com/photos/12.jpg"
        }
    ],
    "meta": {
        "current_page": 1,
        "total": 1
    }
}
 

Request      

GET api/v1/users

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

search   string  optional  

Search by name or email (fuzzy matching). Example: alex

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

Get a single team member by ID.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/users/12" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/users/12"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 12,
    "name": "Alexander Romankó",
    "email": "[email protected]",
    "profile_photo_url": "https://example.com/photos/12.jpg"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/users/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

User ID. Example: 12

Update a team member (admin only).

requires authentication

Only admins (SuperAdmin, OrganizationManager) can update team members. Fields that can be updated (defined in User::API_UPDATABLE_FIELDS):

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/users/12" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"is_active\": true,
    \"can_add_manual_time\": true,
    \"can_move_time\": false,
    \"target_hours\": 40
}"
const url = new URL(
    "https://app.corcava.com/api/v1/users/12"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "is_active": true,
    "can_add_manual_time": true,
    "can_move_time": false,
    "target_hours": 40
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 12,
    "name": "Alexander Romankó",
    "email": "[email protected]",
    "is_active": true,
    "can_add_manual_time": true,
    "can_move_time": false,
    "target_hours": 40
}
 

Example response (403, forbidden):


{
    "message": "Only admins can update team members"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/users/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

User ID. Example: 12

Body Parameters

is_active   boolean  optional  

Enable/disable user. Example: true

can_add_manual_time   boolean  optional  

Allow manual time entry. Example: true

can_move_time   boolean  optional  

Allow moving time. Example: false

target_hours   number  optional  

Weekly target hours. Example: 40

Invite a new team member.

requires authentication

Send an invitation email to a new team member. Only admins (SuperAdmin, OrganizationManager) can invite.

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/users/invite" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"email\": \"[email protected]\",
    \"role\": \"user\",
    \"pay_rate\": 25,
    \"projects\": [
        1,
        2,
        3
    ],
    \"is_manager\": false
}"
const url = new URL(
    "https://app.corcava.com/api/v1/users/invite"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "[email protected]",
    "role": "user",
    "pay_rate": 25,
    "projects": [
        1,
        2,
        3
    ],
    "is_manager": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "message": "Invitation sent successfully",
    "data": {
        "email": "[email protected]",
        "role": "user",
        "pay_rate": 25,
        "projects": [
            1,
            2,
            3
        ]
    }
}
 

Example response (403, forbidden):


{
    "message": "This action is unauthorized."
}
 

Example response (422, already_member):


{
    "message": "This user already belongs to the team."
}
 

Example response (422, has_team):


{
    "message": "User already has a team."
}
 

Request      

POST api/v1/users/invite

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

email   string   

Email address of the person to invite. Example: [email protected]

role   string   

Role to assign. Example: user

pay_rate   number  optional  

Hourly pay rate. Example: 25

projects   string[]  optional  

Array of project IDs to assign.

is_manager   boolean  optional  

Example: false

Tickets

APIs for managing user tickets

These endpoints allow a user to list, create, update, and delete their own tickets. Access is restricted by API key and user ownership. Use auth:api middleware.

Display a list of the authenticated user's tickets.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/tickets" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tickets"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


[
    {
        "id": 39,
        "name": "Login issue",
        "description": "Cannot log in.",
        "status": "new",
        "priority": "high",
        "source": "email",
        "owner_id": 1251,
        "client_id": null,
        "team_id": 514,
        "adds_client_activity": 1,
        "created_at": "2025-10-23T00:00:00.000000Z",
        "updated_at": "2025-10-23T14:37:12.000000Z"
    }
]
 

Request      

GET api/v1/tickets

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Store a newly created ticket.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/tickets" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"\\\"Login issue\\\"\",
    \"description\": \"\\\"Cannot log in.\\\"\",
    \"status\": \"new\",
    \"priority\": \"low\",
    \"source\": \"email\",
    \"client_id\": 16,
    \"contact_id\": 16
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tickets"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "\"Login issue\"",
    "description": "\"Cannot log in.\"",
    "status": "new",
    "priority": "low",
    "source": "email",
    "client_id": 16,
    "contact_id": 16
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 39,
    "name": "Login issue",
    "description": "Cannot log in.",
    "status": "new",
    "priority": "high",
    "source": "email",
    "owner_id": 1251,
    "client_id": null,
    "team_id": 514,
    "adds_client_activity": 1,
    "created_at": "2025-10-23T00:00:00.000000Z",
    "updated_at": "2025-10-23T14:37:12.000000Z"
}
 

Request      

POST api/v1/tickets

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

The name of the ticket. Example: "Login issue"

description   string   

The description of the ticket. Example: "Cannot log in."

status   string   

The status of the ticket. TicketStatusEnum value as string. Example: new

Must be one of:
  • new
  • waiting_on_contact
  • waiting_on_us
  • closed
priority   string   

The priority of the ticket. TicketPriorityEnum value as string. Example: low

Must be one of:
  • low
  • medium
  • high
source   string   

The source of the ticket. TicketSourceEnum value as string. Example: email

Must be one of:
  • chat
  • email
  • form
  • phone
  • other
client_id   integer  optional  

The client ID associated with this ticket. Optional. Example: 16

contact_id   integer  optional  

The contact ID associated with this ticket. Optional. Example: 16

Display the specified ticket (only if it belongs to the user).

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/tickets/39" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tickets/39"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 39,
    "name": "Login issue",
    "description": "Cannot log in.",
    "status": "new",
    "priority": "high",
    "source": "email",
    "owner_id": 1251,
    "client_id": null,
    "team_id": 514,
    "adds_client_activity": 1,
    "created_at": "2025-10-23T00:00:00.000000Z",
    "updated_at": "2025-10-23T14:37:12.000000Z"
}
 

Example response (403, unauthorized):


{
    "message": "Forbidden"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/tickets/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

ticket ID. Example: 39

Update the specified ticket.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/tickets/39" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"\\\"Login issue\\\"\",
    \"description\": \"\\\"Cannot log in.\\\"\",
    \"status\": \"new\",
    \"priority\": \"low\",
    \"source\": \"email\",
    \"client_id\": 16,
    \"contact_id\": 16
}"
const url = new URL(
    "https://app.corcava.com/api/v1/tickets/39"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "\"Login issue\"",
    "description": "\"Cannot log in.\"",
    "status": "new",
    "priority": "low",
    "source": "email",
    "client_id": 16,
    "contact_id": 16
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 39,
    "name": "Login issue",
    "description": "Cannot log in.",
    "status": "new",
    "priority": "high",
    "source": "email",
    "owner_id": 1251,
    "client_id": null,
    "team_id": 514,
    "adds_client_activity": 1,
    "created_at": "2025-10-23T00:00:00.000000Z",
    "updated_at": "2025-10-23T14:37:12.000000Z"
}
 

Example response (403, unauthorized):


{
    "message": "Forbidden"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/tickets/{id}

PATCH api/v1/tickets/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

ticket ID. Example: 39

Body Parameters

name   string   

The name of the ticket. Example: "Login issue"

description   string   

The description of the ticket. Example: "Cannot log in."

status   string   

The status of the ticket. TicketStatusEnum value as string. Example: new

Must be one of:
  • new
  • waiting_on_contact
  • waiting_on_us
  • closed
priority   string   

The priority of the ticket. TicketPriorityEnum value as string. Example: low

Must be one of:
  • low
  • medium
  • high
source   string   

The source of the ticket. TicketSourceEnum value as string. Example: email

Must be one of:
  • chat
  • email
  • form
  • phone
  • other
client_id   integer  optional  

The client ID associated with this ticket. Optional. Example: 16

contact_id   integer  optional  

The contact ID associated with this ticket. Optional. Example: 16

Remove the specified ticket.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/tickets/39" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/tickets/39"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (403, unauthorized):


{
    "message": "Forbidden"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/tickets/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

ticket ID. Example: 39

Time Intervals

APIs for managing time intervals.

Time intervals represent periods of tracked work. These endpoints let you list, create, update, delete, and move time intervals.

Display a paginated list of time intervals.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/time-intervals?project_id=15&user_id=42&date_from=2024-01-01&date_to=2024-12-31&is_invoiced=1&per_page=50" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/time-intervals"
);

const params = {
    "project_id": "15",
    "user_id": "42",
    "date_from": "2024-01-01",
    "date_to": "2024-12-31",
    "is_invoiced": "1",
    "per_page": "50",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "data": [
        {
            "id": 123,
            "project_id": 15,
            "user_id": 42,
            "started_at": "2024-03-15T09:00:00.000000Z",
            "finished_at": "2024-03-15T10:30:00.000000Z",
            "manual_time": true,
            "source": "api",
            "is_invoiced": false,
            "created_at": "2024-03-15T10:30:05.000000Z",
            "updated_at": "2024-03-15T10:30:05.000000Z"
        }
    ],
    "links": {
        "first": "https://example.com/api/v1/time-intervals?page=1",
        "last": "https://example.com/api/v1/time-intervals?page=3",
        "prev": null,
        "next": "https://example.com/api/v1/time-intervals?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "path": "https://example.com/api/v1/time-intervals",
        "per_page": 50,
        "to": 50,
        "total": 125
    }
}
 

Request      

GET api/v1/time-intervals

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

project_id   integer  optional  

Filter intervals by project ID. Example: 15

user_id   integer  optional  

Filter intervals by user ID. Example: 42

date_from   string  optional  

date Filter intervals starting from this date (YYYY-MM-DD). Example: 2024-01-01

date_to   string  optional  

date Filter intervals ending before this date (YYYY-MM-DD). Example: 2024-12-31

is_invoiced   boolean  optional  

Filter by invoiced status. Example: true

per_page   integer  optional  

Number of results per page. Maximum: 100. Example: 50

Display a single time interval.

requires authentication

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/time-intervals/123" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/time-intervals/123"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, success):


{
    "id": 123,
    "project_id": 15,
    "user_id": 42,
    "started_at": "2024-03-15T09:00:00.000000Z",
    "finished_at": "2024-03-15T10:30:00.000000Z",
    "manual_time": true,
    "source": "api",
    "is_invoiced": false,
    "created_at": "2024-03-15T10:30:05.000000Z",
    "updated_at": "2024-03-15T10:30:05.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

GET api/v1/time-intervals/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Time interval ID. Example: 123

Create a new time interval.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/time-intervals" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"project_id\": 15,
    \"started_at\": \"2024-03-15T09:00:00Z\",
    \"finished_at\": \"2024-03-15T10:30:00Z\",
    \"user_id\": 42
}"
const url = new URL(
    "https://app.corcava.com/api/v1/time-intervals"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "project_id": 15,
    "started_at": "2024-03-15T09:00:00Z",
    "finished_at": "2024-03-15T10:30:00Z",
    "user_id": 42
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (201, success):


{
    "id": 123,
    "project_id": 15,
    "user_id": 42,
    "started_at": "2024-03-15T09:00:00.000000Z",
    "finished_at": "2024-03-15T10:30:00.000000Z",
    "manual_time": true,
    "source": "api",
    "is_invoiced": false,
    "created_at": "2024-03-15T10:30:05.000000Z",
    "updated_at": "2024-03-15T10:30:05.000000Z"
}
 

Example response (422, validation_error):


{
    "message": "Project not found"
}
 

Request      

POST api/v1/time-intervals

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

project_id   integer   

Project ID. Example: 15

started_at   datetime   

Start time (ISO 8601). Example: 2024-03-15T09:00:00Z

finished_at   datetime  optional  

End time (ISO 8601). Example: 2024-03-15T10:30:00Z

user_id   integer  optional  

User ID (defaults to authenticated user). Example: 42

Update a time interval.

requires authentication

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/time-intervals/123" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"started_at\": \"2024-03-15T09:00:00Z\",
    \"finished_at\": \"2024-03-15T10:30:00Z\",
    \"project_id\": 15,
    \"user_id\": 42
}"
const url = new URL(
    "https://app.corcava.com/api/v1/time-intervals/123"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "started_at": "2024-03-15T09:00:00Z",
    "finished_at": "2024-03-15T10:30:00Z",
    "project_id": 15,
    "user_id": 42
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "id": 123,
    "project_id": 15,
    "user_id": 42,
    "started_at": "2024-03-15T09:00:00.000000Z",
    "finished_at": "2024-03-15T11:00:00.000000Z",
    "manual_time": true,
    "source": "api",
    "is_invoiced": false,
    "created_at": "2024-03-15T10:30:05.000000Z",
    "updated_at": "2024-03-15T11:05:12.000000Z"
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

PUT api/v1/time-intervals/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Time interval ID. Example: 123

Body Parameters

started_at   datetime  optional  

Start time (ISO 8601). Example: 2024-03-15T09:00:00Z

finished_at   datetime  optional  

End time (ISO 8601). Example: 2024-03-15T10:30:00Z

project_id   integer  optional  

Project ID. Example: 15

user_id   integer  optional  

User ID. Example: 42

Delete a time interval.

requires authentication

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/time-intervals/123" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/time-intervals/123"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Example response (204, success):

Empty response
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Request      

DELETE api/v1/time-intervals/{id}

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Time interval ID. Example: 123

Move a time interval to another project.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/time-intervals/123/move" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"new_project_id\": 18,
    \"reason\": \"Wrong project assignment\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/time-intervals/123/move"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "new_project_id": 18,
    "reason": "Wrong project assignment"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "success": true
}
 

Example response (404, not_found):


{
    "message": "Not found"
}
 

Example response (422, validation_error):


{
    "message": "Project not found"
}
 

Request      

POST api/v1/time-intervals/{id}/move

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   integer   

Time interval ID. Example: 123

Body Parameters

new_project_id   integer   

New project ID. Example: 18

reason   string  optional  

optional Reason for moving. Example: Wrong project assignment

Time Tracking

APIs for managing time tracking via external sources (Telegram bot, Slack bot, Web Agent, etc.). These endpoints allow starting and stopping time intervals manually.

Only users with manual time tracking enabled can use these endpoints.

Start Time Tracking

requires authentication

Start tracking time on a project. Creates a new open time interval. Only available for users with manual time tracking enabled.

Requires either project_id or project_name. Use GET /api/v1/projects to list available projects.

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/time-tracking/start" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"project_id\": 5,
    \"task_id\": 123,
    \"note\": \"Working on homepage\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/time-tracking/start"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "project_id": 5,
    "task_id": 123,
    "note": "Working on homepage"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "status": "started",
    "interval_id": 456,
    "project": {
        "id": 5,
        "name": "Website Redesign"
    },
    "started_at": "2025-12-26T10:30:00.000000Z",
    "message": "Time tracking started on Website Redesign"
}
 

Example response (403, manual_time_disabled):


{
    "error": "Manual time tracking is not enabled for your account."
}
 

Example response (404, project_not_found):


{
    "error": "Project not found or you do not have access to it."
}
 

Example response (409, already_tracking):


{
    "error": "You already have an active time tracking session.",
    "active_interval": {
        "id": 123,
        "project_name": "Other Project",
        "started_at": "2025-12-26T08:00:00.000000Z",
        "duration_hours": 2.5
    }
}
 

Request      

POST api/v1/time-tracking/start

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

project_id   integer   

The project ID to track time on. Example: 5

task_id   integer  optional  

Optional task ID to associate with tracking. Example: 123

note   string  optional  

Optional note for the time entry. Example: Working on homepage

Stop Time Tracking

requires authentication

Stop the current active time tracking session.

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/time-tracking/stop" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"note\": \"Completed homepage design\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/time-tracking/stop"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "note": "Completed homepage design"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200, success):


{
    "status": "stopped",
    "interval_id": 456,
    "project": {
        "id": 5,
        "name": "Website Redesign"
    },
    "started_at": "2025-12-26T10:30:00.000000Z",
    "finished_at": "2025-12-26T12:45:00.000000Z",
    "duration": "2h 15m",
    "message": "Tracked 2h 15m on Website Redesign"
}
 

Example response (404, no_active_tracking):


{
    "error": "No active time tracking session found."
}
 

Request      

POST api/v1/time-tracking/stop

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

note   string  optional  

Optional note to add to the time entry. Example: Completed homepage design

Get Tracking Status

requires authentication

Get the current time tracking status for the authenticated user.

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/time-tracking/status" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/time-tracking/status"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200, tracking_active):


{
    "status": "tracking",
    "interval": {
        "id": 456,
        "project_id": 5,
        "project_name": "Website Redesign",
        "task_id": null,
        "started_at": "2025-12-26T10:30:00.000000Z",
        "duration_hours": 1.5,
        "duration_formatted": "1h 30m"
    }
}
 

Example response (200, not_tracking):


{
    "status": "not_tracking",
    "message": "You are not currently tracking time."
}
 

Request      

GET api/v1/time-tracking/status

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Heartbeat - update last activity timestamp for web tracker.

requires authentication

Only applies to SOURCE_WEB intervals. Idempotent.

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/time-tracking/heartbeat" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/time-tracking/heartbeat"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/v1/time-tracking/heartbeat

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Reconcile - handle away time (stop at last active, keep running, or split).

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/time-tracking/reconcile" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"action\": \"architecto\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/time-tracking/reconcile"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "action": "architecto"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/v1/time-tracking/reconcile

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

action   string   

stop_at_last_active|keep_running|split_idle Example: architecto

Add a note to the current web tracking interval.

requires authentication

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/time-tracking/interval/12/note" \
    --header "X-API-Key: {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"content\": \"Quick break\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/time-tracking/interval/12/note"
);

const headers = {
    "X-API-Key": "{YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "content": "Quick break"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/v1/time-tracking/interval/{timeInterval_id}/note

Headers

X-API-Key      

Example: {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

timeInterval_id   integer   

The ID of the timeInterval. Example: 12

Body Parameters

content   string   

Note content. Example: Quick break

Workflows

Natural-language automation workflows (compiled SQL + tool actions).

GET api/v1/workflows

Example request:
curl --request GET \
    --get "https://app.corcava.com/api/v1/workflows" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/workflows"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: X-Inertia
access-control-allow-origin: *
set-cookie: XSRF-TOKEN=eyJpdiI6IitNbEJNM3BUaDZ2QlJ3a3lSYmtzYWc9PSIsInZhbHVlIjoiTnFIcUVlbDdyMytvRnh6ZzdDUEZxb2dWaStGTzRReUJQbUpyREVWWGNMUGRxMmZJdlNTUEdnQWJJRlFCYjcrT3pXR25sSHRIYnd0Vm4zQ3hnckxTOUdXdE1GUHJadUlnQ0lsckhTeWxSOUtiREtGNWlpNldMUjdDM2NJMldFUG8iLCJtYWMiOiIzNjUwNGVkMDc3M2RmMTNjZDhjMzRjZmI5YTU5ZjhjOTczYTU0NDVkYTc3MmE2MjUzNGZmMTAyNzMxMTdiNjIyIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:22 GMT; Max-Age=172800; path=/; secure; samesite=lax; corcava_session=eyJpdiI6Ilp6SWpsVkRUQTJRamdKakViYlo5dXc9PSIsInZhbHVlIjoiaEFDNmhBLzZscDgzOFJtMzJMaFhGdHZsQ0RXMUQwNjdENmovOFJoV21QVUNUY2VMMi9Lb0VuMTR0RklXdTFLVDRHeUZ4Y2lDK3FCVXVUTkhQUW5ydVRHMmprYlhBMS9pSHRFazNGNjR4Qi9kZStKSy9mQUxOT0pXZXhKVEtNR08iLCJtYWMiOiI3MWRiNGZiZjUzMTMxZDQwY2RmOTBlOTIyZjc1ODcwOTEyMDZiMjJhMTcxZmVjZjdhNzNhZjg4NjdkY2Q3YTkwIiwidGFnIjoiIn0%3D; expires=Thu, 17 Sep 2026 03:18:22 GMT; Max-Age=172800; path=/; secure; httponly; samesite=lax
 

{
    "message": "Authorization required"
}
 

Request      

GET api/v1/workflows

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

POST api/v1/workflows

Example request:
curl --request POST \
    "https://app.corcava.com/api/v1/workflows" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"b\",
    \"source_text\": \"n\",
    \"anchor_type\": \"contact\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/workflows"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "b",
    "source_text": "n",
    "anchor_type": "contact"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/v1/workflows

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

name   string   

Must not be greater than 255 characters. Example: b

source_text   string   

Must not be greater than 10000 characters. Example: n

anchor_type   string  optional  

Example: contact

Must be one of:
  • contact

PUT api/v1/workflows/{id}

Example request:
curl --request PUT \
    "https://app.corcava.com/api/v1/workflows/architecto" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"name\": \"b\",
    \"source_text\": \"n\",
    \"anchor_type\": \"contact\"
}"
const url = new URL(
    "https://app.corcava.com/api/v1/workflows/architecto"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "b",
    "source_text": "n",
    "anchor_type": "contact"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

PUT api/v1/workflows/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the workflow. Example: architecto

Body Parameters

name   string   

Must not be greater than 255 characters. Example: b

source_text   string   

Must not be greater than 10000 characters. Example: n

anchor_type   string  optional  

Example: contact

Must be one of:
  • contact

DELETE api/v1/workflows/{id}

Example request:
curl --request DELETE \
    "https://app.corcava.com/api/v1/workflows/architecto" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://app.corcava.com/api/v1/workflows/architecto"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Request      

DELETE api/v1/workflows/{id}

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

id   string   

The ID of the workflow. Example: architecto