Introduction
Welcome to the Ezus API. Our API follows REST principles, offering a set of HTTP methods that serve as the foundation for Ezus' core functionalities. Its primary purpose is to empower you to programmatically manage your Ezus projects, clients, catalog (suppliers, products, packages), and invoices.
If you're seeking an overview of common use cases achievable through our API, feel free to explore our help center's Integrations section for valuable insights.
For those ready to delve into the details of available methods, you're in the right place. This documentation presents a technical reference for each method in the left-hand section, complemented by code examples in the right-hand section.
While each method possesses its unique specifications, here are some general guidelines:
For any request, you must provide Header Parameters
For GET requests, ensure you also provide the required query parameters
For POST/PUT/DELETE requests, structure your request's body parameters in JSON format (application/json)
Authentication
Principles
Ezus API employs a robust authentication scheme that leverages API Keys and Bearer authentication. To interact with the Ezus API effectively, you'll need two crucial elements:
- An Ezus API key
- User credentials for an active Ezus account
API key
Ezus uses API keys to control access to its API. To obtain your <YOUR_API_KEY>, kindly request it from your account manager. Every request you make to the Ezus API must include this API key as the x-api-key header parameter, like so:
x-api-key: <YOUR_API_KEY>
Bearer Authentication
Upon successfully calling the /login endpoint with valid credentials, you will receive a bearer token, referred to as <YOUR_TOKEN>. This token remains valid for a duration of 12 hours. The Ezus API requires this bearer token to be included in the Authorization header parameter of all subsequent requests.
Authorization: Bearer <YOUR_TOKEN>
POST login
To initiate authentication, your first step is to make a request to the
/loginendpoint:
curl --location 'https://api.ezus.app/login' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"email": "<YOUR_EMAIL>",
"password": "<YOUR_PASSWORD>"
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
email: "<YOUR_EMAIL>",
password: "<YOUR_PASSWORD>",
};
const headers = { "x-api-key": "<YOUR_API_KEY>" };
axios.post(baseUrl + "/login", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"token": "<YOUR_TOKEN>",
"authorization_code": "<YOUR_AUTHORIZATION_CODE>"
}
In subsequent requests, remember to replace
<YOUR_TOKEN>in the Authorization header parameter with the token you received during this authentication process.
HTTP Endpoint
POST https://api.ezus.app/login
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| String | Required Your account email | |
| password | String | Required Your account password |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message. If successful, it also returns a token that you must retain for future API requests, as well as an authorization_code.
The authorization_code is a single-use code valid for 5 minutes, intended to be exchanged on the /token endpoint. If you only use the bearer token, you can safely ignore this field.
POST token
To exchange your authorization code for tokens, make a request to the
/tokenendpoint:
curl --location 'https://api.ezus.app/token' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
"grant_type": "authorization_code",
"code": "<YOUR_AUTHORIZATION_CODE>"
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
grant_type: "authorization_code",
code: "<YOUR_AUTHORIZATION_CODE>",
};
const headers = { "x-api-key": "<YOUR_API_KEY>" };
axios.post(baseUrl + "/token", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"access_token": "<YOUR_ACCESS_TOKEN>",
"refresh_token": "<YOUR_REFRESH_TOKEN>",
"token_type": "Bearer",
"expires_in": 43200
}
Use the
access_tokenas your Bearer token in the Authorization header of subsequent requests. When it expires, call/tokenagain withgrant_typeset torefresh_tokenand yourrefresh_tokento obtain new tokens.
HTTP Endpoint
POST https://api.ezus.app/token
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key. Must be the key the code or refresh token was issued for. |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| grant_type | String | Required authorization_code or refresh_token |
| code | String | Required if grant_type=authorization_code The authorization_code returned by /login |
| refresh_token | String | Required if grant_type=refresh_token The refresh_token returned by your last /token call |
Response
A JSON object containing an access_token (same format and 12-hour lifetime as the token returned by /login), a new refresh_token, the token_type and the access token lifetime in seconds.
Refresh tokens are single-use and valid for 90 days: every call to /token invalidates the code or refresh token you presented and returns a new refresh_token (you should store the one from the latest response). Presenting an already-used code or refresh token revokes all tokens issued from the same authorization flow, and you will need to authenticate again through /login.
GET me
Returns the authentication context of your call: the user your bearer token belongs to, its account, the lifetime of the token, and what the role of that user grants. Add include=config to also receive the configuration of the account.
curl --location 'https://api.ezus.app/me' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/me", headers);
This request returns a structured JSON object:
{
"error": "false",
"user": {
"email": "tommy@e-corp.com",
"first_name": "Tommy",
"last_name": "Atkins",
"role": "admin"
},
"account": {
"name": "E-Corp Travels",
"currency": "EUR"
},
"token": {
"issued_at": "2026-09-19T10:00:00Z",
"expires_at": "2026-09-19T22:00:00Z"
},
"scopes": {
"projects": "333",
"clients": "310",
"travellers": "333",
"suppliers": "333",
"invoices": "300",
"tasks": "333",
"catalog": "333",
"models": "300",
"library": "333",
"invoices_suppliers": "300",
"territories": "333",
"categories": "333",
"invoices_finalize": "000",
"invoices_stats": "000",
"stripe_payments": "000",
"projects_close": "333",
"steps_catalog": "333",
"settings": "000",
"billing_team": "000",
"export": "333",
"templates_edit": "333",
"client_space": "333"
},
"server_time": "2026-09-19T10:12:03Z"
}
HTTP Endpoint
GET https://api.ezus.app/me
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| include | String | Comma-separated list of objects to add to the response. Possible values: config. Without it, the response carries no config object; any other value is refused with an error |
Response
A JSON object that contains your authentication context.
| Property | Type | Description |
|---|---|---|
| user | JSON | The user your token was issued for (Authenticated User) |
| account | JSON | The account this user works for (Account) |
| token | JSON | Lifetime of your bearer token (Token) |
| scopes | JSON | What the role of this user grants (Scopes) |
| server_time | String | Current server time, UTC |
| config | JSON | Configuration of the account, only with include=config (Config) |
Projects
GET projects
Returns a list of your projects, sorted from the most recent to the oldest, with the newest projects appearing first. The list of projects returned is paginated (50 per 50): to call the 50 next items in the list, call the route with the next_token query parameter.
curl --location 'https://api.ezus.app/projects' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/projects", headers);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "<NEXT_TOKEN>",
"size": 338,
"data_size": 50,
"page": 1,
"projects": [
{
"reference": "project_reference",
"info_number": "202306001-P",
"info_title": "Paris fashion week 2024",
"info_stage_reference": "confirmed",
"info_stage": "Confirmed",
"info_notes": "Jane has verbally confirmed our quotation",
"trip_date_in": "2024-03-01",
"trip_date_out": "2024-03-09",
"trip_duration": 8,
"currency": "€",
"created_at": "2024-06-18",
"updated_at": "2024-06-19",
"sales_manager": {
"email": "travel-design@e-corp.com",
"first_name": "Alice",
"last_name": "Tate",
"agency": "Paris Agency"
},
"project_manager": {
"email": "no-reply@e-corp.com",
"first_name": "Joe",
"last_name": "Shmoe",
"agency": "Paris Agency"
}
}
]
}
HTTP Endpoint
GET https://api.ezus.app/projects
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| next_token | String | Specify this parameter if you want to retrieve the following elements of a given list query |
| info_stage_reference | String | You can filter projects that are in a specific stage. The stage of the project must be indicated by its technical name |
| trip_date_in | Date | You can filter projects assigned to a specific or an intersection of trip start date. Expected format: “YYYY-MM-DD” or “YYYY-MM-DD,YYYY-MM-DD”. See Date Format for more details. |
| trip_date_out | Date | You can filter projects assigned to a specific or an intersection of trip end date. Expected format: “YYYY-MM-DD” or “YYYY-MM-DD,YYYY-MM-DD”. See Date Format for more details. |
| created_at | Date | You can filter projects assigned to a specific or an intersection of creation date. Expected format: “YYYY-MM-DD” or “YYYY-MM-DD,YYYY-MM-DD”. See Date Format for more details. |
| updated_at | Date | You can filter projects assigned to a specific or an intersection of last update date. Expected format: “YYYY-MM-DD” or “YYYY-MM-DD,YYYY-MM-DD”. See Date Format for more details. |
| sales_manager | String | Provide either the sales manager's email address or "None". Expected format: "john.doe@e-corp.com" or "None". |
| project_manager | String | Provide either the project manager's email address or "None". Expected format: "john.doe@e-corp.com" or "None". |
| from_programs_catalog | Boolean | Optional. Defaults to false. When set to true, retrieves all projects from the programs catalog. |
Response
A JSON object containing the project information with properties like:
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all projects have not been returned. Use it in another call to access the following projects |
| size | Number | The total number of projects available with these filters |
| data_size | Number | Number of projects returned on the current page |
| page | Number | The page number |
| projects | Array | An array of JSON objects, each representing a project. Each object follows the GET project response structure, with two differences: the alternatives and custom_fields arrays are omitted ; the main alternative's trip_date_in, trip_date_out, trip_duration are returned directly at the project level. |
GET project
This API endpoint retrieves detailed information about a specific project in Ezus. Add include=config to also receive the settings its prices are computed with.
curl --location 'https://api.ezus.app/project?reference=project_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/project?reference=project_reference", headers);
This request returns a structured JSON object:
{
"error": "false",
"reference": "project_reference",
"info_number": "202306001-P",
"info_title": "Paris fashion week 2024",
"info_stage_reference": "confirmed",
"info_stage": "Confirmed",
"info_notes": "Jane has verbally confirmed our quotation",
"currency": "€",
"created_at": "2024-06-18",
"updated_at": "2024-06-19",
"sales_manager": {
"email": "travel-design@e-corp.com",
"first_name": "Alice",
"last_name": "Tate",
"agency": "Paris Agency"
},
"project_manager": {
"email": "no-reply@e-corp.com",
"first_name": "Joe",
"last_name": "Shmoe",
"agency": "Paris Agency"
},
"alternatives": [
{
"reference": "550e8400-e29b-41d4-a716-446655440000",
"alternative_title": "Main Alternative",
"lang": "fr-FR",
"is_main": true,
"is_sig": false,
"trip_date_in": "2024-03-01",
"trip_date_out": "2024-03-09",
"trip_duration": 9,
"trip_people": "15",
"trip_destination_reference": "destination_reference",
"trip_destination": "France",
"trip_subdestination_reference ": "subdestination_reference",
"trip_subdestination": "Paris",
"trip_budget": 90000,
"budget_actual": 88750,
"budget_actual_excl_taxes ": 77950,
"budget_margin_gross": 2500,
"budget_margin_net": 1000,
"budget_purchases": 74500,
"financial_invoiced": 48000,
"financial_collected": 48000,
"financial_purchases": 72820,
"financial_spendings": 12820,
"destinations": {
"size": 3,
"data": [
{
"reference": "destination_reference",
"name": "France",
"subdestination_reference": "subdestination_reference",
"subdestination_name": "Paris"
},
{
"reference": "destination_reference",
"name": "France",
"subdestination_reference": "subdestination_reference1-2",
"subdestination_name": "Lyon"
},
{
"reference": "destination_reference2",
"name": "Italy",
"subdestination_reference": "subdestination_reference2-1",
"subdestination_name": "Milan"
}
]
},
"client": {
"reference": "client_reference",
"type": "enterprise",
"company_name": "MOKE INTERNATIONAL LIMITED",
"first_name": "Jane",
"last_name": "Doe",
"email": "contact@moke-international.com"
},
"client_space": {
"is_live": true,
"url": "https://custom-domain.com/your-space-slug",
"description": "Description of the client space",
"image_url": "https://image.jpg"
},
"brand": {
"title": "INTERNATIONAL LIMITED",
"company_name": "MOKE INTERNATIONAL LIMITED",
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010"
},
"email": "travel-design@e-corp.com",
"phone": "0101010101",
"website": "www.moke_ltd.com",
"vat_number": "GB 240-635-038",
"company_number": "09728676"
}
}
],
"custom_fields": [
{
"name": "CustomField",
"value": "Value"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/project
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the project to retrieve |
| include | String | Comma-separated list of objects to add to the response. Possible values: config. Without it, the response carries no config object; any other value is refused with an error |
Response
A JSON object containing the project information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the project |
| info_number | String | File number that appears in the project record. Not to be confused with reference |
| info_title | String | The title of the project |
| info_stage_reference | String | Technical name of the stage of the project (confirmed, received, paid...) |
| info_stage | String | The stage of the project (Confirmed, Received, Paid...) |
| info_notes | String | Notes on the project |
| currency | String | Default currency of the project |
| created_at | Date | Date of creation |
| updated_at | Date | Date of the last update |
| sales_manager | JSON | JSON object representing the sales manager (User) |
| project_manager | JSON | JSON object representing the project manager (User) |
| alternatives | Array | Array of JSON alternatives (Alternatives) |
| custom_fields | Array | Array of JSON custom fields (Custom fields) |
| config | JSON | Pricing settings of the project, only with include=config (Project Config) |
GET project-documents
Returns the list of documents of your project, sorted from the most recent to the oldest.
curl --location 'https://api.ezus.app/project-documents?reference=project_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/project-documents?reference=project_reference", headers);
This request returns a structured JSON object:
{
"error": "false",
"reference": "project_reference",
"alternative_order": "0",
"documents": [
{
"type": "custom",
"title": "documentName",
"url": "https://ezus.io/2023_101010.pdf"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/project-documents
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the project to retrieve documents from |
| alternative_order | Number | Specifies the alternative order in the project to retrieve documents from. If not provided, defaults to 0 for main alternative |
Response
A JSON object containing the project documents information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the project |
| alternative_order | Number | The alternative order; 0 is for main alternative |
| documents | Array | An array of JSON objects, each representing a document. The documents are sorted by their creation date, with the most recently created appearing first. Each document includes the following fields: type, title, and url. |
GET project-steps
Returns the list of steps of your project, sorted from the most recent to the oldest.
curl --location 'https://api.ezus.app/project-steps?reference=project_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/project-steps?reference=project_reference", headers);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "<NEXT_TOKEN>",
"reference": "project_reference",
"alternative_order": "0",
"size": 1,
"data_size": 1,
"page": 1,
"steps": [
{
"reference": "activity_reference",
"sample_step_reference": "sample_step_reference",
"type": "activity",
"name": "activityTitle",
"category": "restaurant",
"date_start": "2024-10-01 10:00:00",
"date_end": "2024-10-01 12:00:00",
"people": 4,
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
},
"description": {
"short": "Short description of the activity",
"long": "Long description of the activity"
},
"items": [
{
"reference": "item_reference",
"name": "item_title",
"product_reference": "product_reference",
"supplier_reference": "supplier_reference",
"quantity": 2,
"purchase_price": 150,
"purchase_price_excl_taxes": 125,
"sales_price": 200,
"sales_price_excl_taxes": 166.67,
"is_optional": false,
"notes": "Notes about the item",
"booked": false
}
],
"medias": ["https://image.jpg", "https://image2.jpg"],
"custom_fields": [
{
"name": "CustomField",
"value": "Value"
}
]
}
],
"supplements": {
"fees": [
{
"reference": "fee_reference",
"label": "Main fee",
"mode": "flat",
"value": 2000,
"amount": 2000,
"amount_excl_taxes": 1666.67,
"notes": "Some notes"
}
],
"discounts": [
{
"reference": "discount_reference",
"label": "Main discount",
"mode": "percentage",
"value": 10,
"amount": 1000,
"amount_excl_taxes": 833.33,
"notes": "Some notes"
}
]
}
}
HTTP Endpoint
GET https://api.ezus.app/project-steps
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the project to retrieve documents from |
| alternative_order | Number | Specifies the alternative order in the project to retrieve documents from. If not provided, defaults to 0 for main alternative |
| from_steps_catalog | Boolean | Optional. Defaults to false. When set to true, retrieves all the sample steps and overrides the reference and alternative_order query parameters |
Response
A JSON object containing the project documents information with properties like:
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all project steps have not been returned. Use it in another call to access the following ones |
| reference | String | The reference of the project |
| alternative_order | Number | The alternative order; 0 is for main alternative |
| size | Number | The total number of projects available with these filters |
| data_size | Number | Number of projects returned on the current page |
| page | Number | The page number |
| steps | Array | Array of JSON steps (Steps) |
| supplements | JSON | JSON object containing the fees and discounts supplements of the project (Supplements) |
GET project-travellers
Returns the list of travellers in your project.
curl --location 'https://api.ezus.app/project-travellers?reference=project_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/project-travellers?reference=project_reference", headers);
This request returns a structured JSON object:
{
"error": "false",
"reference": "project_reference",
"alternative_order": 0,
"size": "2",
"travellers": [
{
"reference": "traveller_reference",
"email": "emily.johnson@example.com",
"first_name": "Emily",
"last_name": "Johnson",
"phone": "+1-555-123-4567",
"project_group_reference": "project_group_reference",
"custom_field1": "value1.1",
"custom_field2": "value2.1"
},
{
"reference": "traveller_reference",
"email": "michael.smith@example.com",
"first_name": "Michael",
"last_name": "Smith",
"phone": "+1-555-987-6543",
"project_group_reference": null,
"custom_field1": "value1.2",
"custom_field2": "value2.2"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/project-travellers
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the project to retrieve travellers from |
| alternative_order | Number | Specifies the alternative order in the project to retrieve travellers from. If not provided, defaults to 0 for main alternative |
Response
A JSON object containing the project travellers information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the project |
| alternative_order | Number | The alternative order; 0 is for main alternative |
| size | Number | Total travellers in the project |
| travellers | Array | Array of JSON travellers (Travellers) |
GET project-groups
Returns the groups of your project in group mode (GIR), with their travellers, lines and invoices, and what no group holds.
curl --location 'https://api.ezus.app/project-groups?reference=project_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/project-groups?reference=project_reference", headers);
This request returns a structured JSON object:
{
"error": "false",
"reference": "project_reference",
"alternative_order": 0,
"size": 1,
"groups": [
{
"reference": "project_group_reference",
"name": "Group A",
"pax": 1,
"primary_traveller_reference": "traveller_reference",
"travellers": [
{
"reference": "traveller_reference",
"first_name": "Emily",
"last_name": "Johnson",
"email": "emily.johnson@example.com"
}
],
"items": [
{
"reference": "item_reference",
"project_step_reference": "project_step_reference",
"name": "item_title",
"pax": 1,
"quantity": 3
}
],
"invoices": [
{
"reference": "invoice_reference"
}
]
}
],
"unattributed": {
"travellers": [
{
"reference": "traveller_reference",
"first_name": "Michael",
"last_name": "Smith",
"email": "michael.smith@example.com"
}
],
"items": [
{
"reference": "item_reference",
"project_step_reference": "project_step_reference",
"name": "item_title"
}
],
"invoices": []
}
}
HTTP Endpoint
GET https://api.ezus.app/project-groups
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the project to retrieve groups from |
| alternative_order | Number | Specifies the alternative order in the project to retrieve groups from. If not provided, defaults to 0 for main alternative |
Response
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the project |
| alternative_order | Number | The alternative order; 0 is for main alternative |
| size | Number | Number of groups of the alternative |
| groups | Array | Array of JSON groups (Groups) |
| unattributed | JSON | What no group of the alternative holds (Unattributed) |
POST projects-upsert
This API endpoint can create, duplicate, or update a project. If the provided reference matches an existing project, that project is updated. If no match is found, a new project is created using the provided reference, or a randomly generated one if none is supplied and project_reference is not provided. When project_reference is specified, a new project is created by duplicating the existing project identified by project_reference with the provided reference or a random one.
Error messages
- Sales manager not found →
sales_manager_email must be the email of an active user of the account
curl --location 'https://api.ezus.app/projects-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data-raw '{
"reference": "project_reference",
"project_reference": "project_type_reference",
"info_number": "202306001-P",
"info_title": "Paris fashion week 2024",
"info_stage_reference": "received",
"trip_date_in": "2023-03-01",
"trip_date_out": "2023-03-09",
"trip_budget": "90000",
"trip_people": "15",
"sales_manager_email": "travel-design@e-corp.com",
"client_reference": "client_reference",
"trip_destination_reference": "destination_reference",
"trip_subdestination_reference": "subdestination_reference",
"custom_fields": [
{"name": "field_name", "value": "field_value" }
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "project_reference",
project_reference: "project_type_reference",
info_number: "202306001-P",
info_title: "Paris fashion week 2024",
info_stage_reference: "received",
trip_date_in: "2023-03-01",
trip_date_out: "2023-03-09",
trip_budget: "90000",
trip_people: "15",
sales_manager_email: "travel-design@e-corp.com",
client_reference: "client_reference",
trip_destination_reference: "destination_reference",
trip_subdestination_reference: "subdestination_reference",
custom_fields: [{ name: "field_name", value: "field_value" }],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/projects-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Project successfully created",
"reference": "project_reference",
"info_number": "202306001-P",
"client_reference": "client_reference"
}
HTTP Endpoint
POST https://api.ezus.app/projects-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | If provided, the unique reference associated with the project you want to update or create (or a random one will be generated). |
| mode | String | Optional. upsert (default) updates the project matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing project. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. Nothing is created or updated when the call fails. |
| project_reference | String | If provided, the project_reference is used to duplicate an existing project. For the duplication to succeed, the reference field must not match any existing project. If the info_number, info_title, info_stage_reference, trip_budget, trip_people, sales_manager_email and client_reference fields are filled in, they are used. The fields trip_date_in and trip_date_out are skipped. |
| info_number | String | File number that appears in the project record. Not to be confused with reference |
| info_title | String | Title of the project. This parameter is required if you create a new project |
| info_stage_reference | String | Stage of the project: Please use the technical name of the stage you intend to apply. If no specific stage is found, a default stage will be automatically assigned upon adding the project. |
| trip_date_in | Date | Date of the project's start in "YYYY-MM-DD" format (only settable when creating a new project). If not provided or if not formatted correctly, or if duration > 40 days or if trip_date_in > trip_date_out, project will be set as 1 day and trip_date_in as today. |
| trip_date_out | Date | Date of the project's end in "YYYY-MM-DD" format (only settable when creating a new project). If not provided or if not formatted correctly, or if duration > 40 days or if trip_date_in > trip_date_out, project will be set as 1 day and trip_date_out as today. |
| trip_budget | Number | Forecasted budget for the project |
| trip_people | Number | Number of people in the project (only settable when creating a new project) |
| sales_manager_email | Email of an active Ezus user of your account, set as the sales manager of the project. An unknown email, or the email of a deleted or deactivated user, is rejected. | |
| client_reference | String | Reference or email of an existing client in your Ezus account to link to the project (only settable when creating a new project) |
| trip_destination_reference | String | Reference of the destination to link to the project. To reset the destination, you can put '0'. |
| trip_subdestination_reference | String | Reference of the sub-destination to link to the project. To reset the sub-destination, you can put '0'. If the trip_destination_reference is not provided, the trip_subdestination_reference will be ignored. |
| custom_fields | Array | Array of JSON custom fields (Custom fields) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of project action was created |
| reference | String | The reference for the project, which you should store for future updates or retrievals |
| info_number | String | File number that appears in the project record. Not to be confused with reference |
| client_reference | String | The reference for the client, which you should store for future updates or retrievals |
POST project-documents-create
This API endpoint generates a PDF document from a given link within the specified project.
curl --location 'https://api.ezus.app/project-documents-create' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"project_reference": "project_reference",
"title": "Document PDF",
"link": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
project_reference: "project_reference",
title: "Document PDF",
result:
"https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/project-documents-create", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"result": "<LINK>"
}
HTTP Endpoint
POST https://api.ezus.app/project-documents-create
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| project_reference | String | Required The project reference in which you want to create a document |
| title | String | Title of the document |
| link | Link | Required URL of the document (only supports PDF format and must be publicly accessible) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| result | Link | The URL link of the document after uploading the document |
POST project-steps-upsert
This endpoint updates an existing step when the provided reference matches a step in your account. If no match is found, a new step is created using the provided reference, or a randomly generated one if none is supplied. Note that the following fields are used only during creation and are ignored on update: project_reference, alternative_order, type, date_start, date_end.
Use the field from_steps_catalog to update an existing sample step when the provided reference matches a sample step in your account. If no match is found, a new sample step is created using the provided reference, or a randomly generated one if none is supplied.
Note that the dates provided are not stored as they are, but are normalised to January 1950. The delta between date_end and date_start must not exceed the number of days in the sample steps catalog. Dates can only be modified if both date_start and date_end are specified. Note that the following fields are ignored during creation and update: project_reference, alternative_order. Note that the following fields are used only during creation and are ignored on update: type.
Use the field sample_step_reference to create a step in a project from a sample step of the catalog. The step is a copy of the sample step: title, type, category, people, address, descriptions, items, medias and custom fields. Only reference, project_reference, alternative_order, date_start, date_end and custom_fields are read from the request; custom_fields are applied on top of the copied ones, and every other field is ignored. The sample step must be available in the language of the project (one of the languages set on the sample step in the steps catalog). This field can only be used to create a step, not to update one, and cannot be combined with from_steps_catalog. The sample step a project step was created from is returned by GET project-steps.
curl --location 'https://api.ezus.app/project-steps-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"from_steps_catalog": false,
"reference": "project_step_reference",
"project_reference": "project_reference",
"alternative_order": "0",
"name": "activity Title",
"type": "activity",
"category": "restaurant",
"people": "4",
"date_start": "2025-10-03 10:00:00",
"date_end": "2025-10-03 12:00:00",
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
},
"description": {
"short": "Short description of the activity",
"long": "Long description of the activity"
},
"custom_fields": [
{"name": "field_name", "value": "field_value"}
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
from_steps_catalog: false,
reference: "project_step_reference",
project_reference: "project_reference",
alternative_order: "0",
name: "activity Title",
type: "activity",
category: "restaurant",
people: "4",
date_start: "2025-10-03 10:00:00",
date_end: "2025-10-03 12:00:00",
address: {
label: "58 Rue de Paradis",
city: "Paris",
country: "France",
zip: "75010",
geo: {
x: 48.875761,
y: 2.348727,
},
},
description: {
short: "Short description of the activity",
long: "Long description of the activity",
},
custom_fields: [{ name: "field_name", value: "field_value" }],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/project-steps-upsert", body, headers);
curl --location 'https://api.ezus.app/project-steps-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"from_steps_catalog": true,
"reference": "project_sample_step_reference",
"name": "activity Title",
"type": "activity",
"category": "restaurant",
"people": "4",
"date_start": "2025-10-03 10:00:00",
"date_end": "2025-10-03 12:00:00",
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
},
"custom_fields": [
{"name": "field_name", "value": "field_value"}
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
from_steps_catalog: true,
reference: "project_sample_step_reference",
name: "activity Title",
type: "activity",
category: "restaurant",
people: "4",
date_start: "2025-10-03 10:00:00",
date_end: "2025-10-03 12:00:00",
address: {
label: "58 Rue de Paradis",
city: "Paris",
country: "France",
zip: "75010",
geo: {
x: 48.875761,
y: 2.348727,
},
},
custom_fields: [{ name: "field_name", value: "field_value" }],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/project-steps-upsert", body, headers);
curl --location 'https://api.ezus.app/project-steps-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"sample_step_reference": "sample_step_reference",
"project_reference": "project_reference",
"alternative_order": "0",
"date_start": "2025-10-03 10:00:00",
"date_end": "2025-10-03 12:00:00"
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
sample_step_reference: "sample_step_reference",
project_reference: "project_reference",
alternative_order: "0",
date_start: "2025-10-03 10:00:00",
date_end: "2025-10-03 12:00:00",
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/project-steps-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Project step successfully created",
"reference": "project_step_reference"
}
HTTP Endpoint
POST https://api.ezus.app/project-steps-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| from_steps_catalog | Boolean | Optional. Default to false. When set to true, create or update sample step from catalog. |
| sample_step_reference | String | Optional. The reference of a sample step of the catalog to create the step from. Only used to create a step: the request is rejected on update, when the reference does not match a sample step of your account, when the sample step is not available in the language of the project, or when from_steps_catalog is true. With this field, project_reference, date_start and date_end are the only required fields; name, type, category, people, address and description are ignored and come from the sample step. |
| reference | String | If provided, the unique reference associated to the step you want to update. If you specify a reference during creation, this value will be used as the step reference. It must be a maximum of 64 characters. |
| mode | String | Optional. upsert (default) updates the step matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing step. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. Nothing is created or updated when the call fails. |
| project_reference | String | The project reference in which you want to create an step. This field is ignored during update or when using the from_steps_catalog field. |
| alternative_order | String | Specifies the alternative project order from which to create or update the step. If not provided, defaults to 0 for main alternative. This field is required to create a step. This field is ignored during update or when using the from_steps_catalog field. |
| name | String | Title of the step. This field is required to create a step. This field is optional on update. |
| type | String | Three options exist: accom, activity, transport. This field is required to create a step. This field is ignored on update. |
| category | String | Category of the step. You must provide the technical name of the category. If not specified during creation, the default value will be the main category of the account. |
| people | String | Number of people in the activity. You can use a number or P. If not specified during creation, P will be used as the default value. P represents the number of people in the project. |
| date_start | String | Start date and time of the step. Must be within the dates of the alternative where the step is created. This field is required to create a step. This field is ignored on step update. This field can be completed when updating a sample step, but both dates are required. The date format must be as follows, e.g.: 2024-10-01 12:00:00. |
| date_end | String | End date and time of the step. Must be within the dates of the alternative where the step is created. This field is required to create a step. This field is ignored on step update. This field can be completed when updating the sample step, but both dates are required. The date format must be as follows, e.g.: 2024-10-01 12:00:00. |
| address | Object | JSON object address (Address) |
| description | JSON | JSON object representing the short and long description of the step. |
| custom_fields | Array | An array of JSON custom fields (Custom fields) for the step. |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | If the project has been updated and created |
| reference | String | The reference of the activity that was created or updated |
POST project-steps-items-upsert
This endpoint allows you to create or update multiple items within project step(s) in batch mode (maximum 100 items per request).
The endpoint works in upsert mode: if the provided reference matches an existing item in your account and belongs to the specified step, the item is updated. Otherwise, a new item is created.
curl --location 'https://api.ezus.app/project-steps-items-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '[
{
"project_step_reference": "project_step_reference",
"name": "item_creation_minimal"
},
{
"project_step_reference": "project_step_reference",
"reference": "item_reference",
"product_reference": "product_reference",
"name": "item_update_maximal",
"quantity": 2,
"currency": "USD",
"purchase_price": 150,
"sales_price": 200,
"vat_rate": 20,
"vat_regime": "classic"
}
]'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = [
{
project_step_reference: "project_step_reference",
name: "item_creation_minimal",
},
{
project_step_reference: "project_step_reference",
reference: "item_reference",
product_reference: "product_reference",
name: "item_update_maximal",
quantity: 2,
currency: "USD",
purchase_price: 150,
sales_price: 200,
vat_rate: 20,
vat_regime: "classic",
},
];
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/project-steps-items-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "1 item successfully created ; 1 item successfully updated",
"references": ["project_step_item_reference", "item_reference"]
}
Error response example:
{
"error": "true",
"message": "Invalid input detected: item[0].'vat_regime'. It must be classic, margin or none. The operation could not be processed due to this error"
}
HTTP Endpoint
POST https://api.ezus.app/project-steps-items-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
The request body must be an array of item objects (maximum 100 items).
| Parameter | Type | Description |
|---|---|---|
| project_step_reference | String | Required The project step reference in which you want to create or update an item. Must match a valid, non-deleted step belonging to your account. |
| reference | String | If provided, the unique reference associated to the item you want to update. If you specify a reference during creation, this value will be used as the item reference (max 64 characters). If not provided, a UUID v4 is automatically generated. |
| mode | String | Optional, per item. upsert (default) updates the item matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing item. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. One failing item rejects the whole request before anything is written; the message lists the references at fault. |
| product_reference | String | Reference of the product to link to the item. This field is optional. If provided, it must match a valid product reference in your account. When linking a product to your item, it will inherit its name, quantity, currency, purchase_price, sales_price, vat_rate and vat_regime by default on the creation only. |
| name | String | Title of the item. Cannot be empty. This field is required to create an item if the product_reference is not provided. This field is optional on update. |
| quantity | Number | Quantity of the item. Default value on creation: 1. If this item is linked to a product, it will trigger a tariff recalculation based on the product's pricing rules. |
| currency | String | Currency ISO code (e.g., USD, EUR). Default value on creation: the project's sales currency. Must be present in the project's currencies else it will throw an error. |
| purchase_price | Number | The unit purchase price of the item (including taxes). Default value on creation: 0. See Price behavior for more details. |
| sales_price | Number | The unit sales price of the item (including taxes). Default value on creation: 0. See Price behavior for more details. |
| vat_rate | Number | VAT rate in percentage (e.g., 20 for 20%). Default value on creation: the project's vat_rate. |
| vat_regime | String | VAT regime: classic, margin, or none. Default value on creation: the project's VAT regime. |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Summary of actions performed (e.g., "1 item successfully created ; 1 item successfully updated") |
| references | Array | List of references of the items that were created or updated (UUIDs for auto-generated, provided references otherwise) |
Price behavior
When creating an item here are the following rules that will apply if the project is in "Per product" calculation mode:
- If neither
purchase_pricenorsales_priceis provided on INSERT:purchase_price=sales_price=0 - If
purchase_priceis provided butsales_priceis not on INSERT:sales_price=purchase_price - If
sales_priceis provided butpurchase_priceis not on INSERT:purchase_price=sales_price
For project in "Global" calculation mode:
- If no price is provided on INSERT:
sales_price=purchase_price=0 - If
sales_priceprovided andpurchase_pricenot provided (INSERT or UPDATE):purchase_price=sales_price - If
purchase_priceprovided andsales_pricenot provided (INSERT or UPDATE):sales_price=purchase_price - If both
purchase_priceandsales_priceare provided (INSERT or UPDATE):sales_pricetakes priority,purchase_price=sales_price
POST project-travellers-create
Creates travellers for a project.
This endpoint replaces all existing travellers for the selected project alternative.
If the project already has travellers, they will be deleted and replaced by the travellers provided in this request.
Note: When creating travellers with custom fields, only custom fields of type text are currently supported.
Note: Travellers can only be created if the project's defined number of travelers is greater than or equal to the number of travellers provided in the request. If the input exceeds the project's traveler count, the request will be rejected.
curl --location 'https://api.ezus.app/project-travellers-create' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"reference": "project_reference",
"alternative_order": 0,
"travellers": [
{
"email": "emily.johnson@example.com",
"first_name": "Emily",
"last_name": "Johnson",
"phone": "+1-555-123-4567",
"custom_field1": "value1.1",
"custom_field2": "value2.1"
}
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "project_reference",
alternative_order: 0,
travellers: [
{
email: "emily.johnson@example.com",
first_name: "Emily",
last_name: "Johnson",
phone: "+1-555-123-4567",
custom_field1: "value1.1",
custom_field2: "value2.1",
},
],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/project-travellers-create", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Travellers successfully created"
}
HTTP Endpoint
POST https://api.ezus.app/project-travellers-create
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The project reference in which you want to create travellers |
| alternative_order | Number | Specifies the alternative order in the project to create travellers from. If not provided, defaults to 0 for main alternative |
| travellers | Array | Array of JSON travellers (Travellers) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | If the travellers have been created |
Travellers
GET travellers
Returns a list of your travellers. The list returned is paginated (50 per 50): to call the 50 next items in the list, call the route with the next_token query parameter.
curl --location 'https://api.ezus.app/travelllers' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/travellers", headers);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "<NEXT_TOKEN>",
"size": 363,
"data_size": 50,
"page": 1,
"travellers": [
{
"reference": "<TRAVELLER_REFERENCE>",
"created_at": "2026-08-24 01:23:45",
"updated_at": "2026-08-24 12:34:56",
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@travellers.example",
"phone": "+1-555-123-4567",
"projects": [
{
"project_reference": "<PROJECT_REFERENCE>",
"alternative_reference": "<ALTERNATIVE_REFERENCE>"
}
],
"my_custom_field": "my custom value"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/travellers
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| next_token | String | Specify this parameter if you want to retrieve the following elements of a given list query |
Response
A JSON object containing the project information with properties like:
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all travellers have not been returned. Use it in another call to access the following travellers |
| size | Number | The total number of travellers available with these filters |
| data_size | Number | Number of travellers returned on the current page |
| page | Number | The page number |
| travellers | Array | An array of JSON objects, each representing a traveller. |
Clients
GET clients
Returns a list of your clients, sorted from the newest to the oldest, with the most recent clients appearing first. The list of clients returned is paginated (50 per 50): to call the 50 next items in the list, call the route with the next_token query parameter.
curl --location 'https://api.ezus.app/clients' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/clients", headers);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "<NEXT_TOKEN>",
"size": 338,
"data_size": 50,
"page": 1,
"clients": [
{
"reference": "client_reference",
"info_number": "202306001-C",
"type": "enterprise",
"company_name": "MOKE INTERNATIONAL LIMITED",
"info_notes": "This prospect looks interesting to follow",
"website": "www.moke_ltd.com",
"vat_number": "GB 240-635-038",
"company_number": "09728676",
"predefined_net_margin_rate": 15,
"user": {
"email": "tommy@e-corp.com",
"first_name": "Tommy",
"last_name": "Atkins",
"agency": "Paris Agency"
},
"email": "contact@moke-international.com",
"first_name": "Jane",
"last_name": "Doe",
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
}
}
]
}
HTTP Endpoint
GET https://api.ezus.app/clients
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| next_token | String | Specify this parameter if you want to retrieve the following elements of a given list query. |
| reference | Dynamic filter | You can filter clients with a specific reference |
| info_number | Dynamic filter | You can filter clients with a specific info_number, file number that appears in the client record. Not to be confused with reference |
| type | String | You can filter clients by their type. Either enterprise or individual |
| Dynamic filter | You can filter clients by email. This filter works for both enterprise clients (uses the main contact’s email) and individual clients |
Response
A JSON object containing the client information with properties like:
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all clients have not been returned. Use it in another call to access the following clients |
| size | Number | The total number of clients available with these filters |
| data_size | Number | Number of clients returned on the current page |
| page | Number | The page number |
| clients | Array | An array of JSON objects, each representing a client. These objects are formatted according to a simplified version of the GET client response structure. (GET client) |
GET client
This API endpoint retrieves detailed information about a specific client in Ezus.
curl --location 'https://api.ezus.app/client?reference=client_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/client?reference=client_reference", headers);
This request returns a structured JSON object:
{
"error": "false",
"reference": "client_reference",
"info_number": "202306001-C",
"type": "enterprise",
"company_name": "MOKE INTERNATIONAL LIMITED",
"info_notes": "This prospect looks interesting to follow",
"website": "www.moke_ltd.com",
"vat_number": "GB 240-635-038",
"company_number": "09728676",
"predefined_net_margin_rate": 15,
"user": {
"email": "tommy@e-corp.com",
"first_name": "Tommy",
"last_name": "Atkins",
"agency": "Paris Agency"
},
"email": "contact@moke-international.com",
"first_name": "Jane",
"last_name": "Doe",
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
},
"projects": {
"data": [
{
"reference": "project_reference",
"info_title": "Project title"
}
],
"size": 1
},
"contacts": {
"data": [
{
"reference": "contact_reference",
"email": "contact@moke.com",
"first_name": "Jane",
"last_name": "Doe",
"title": "CEO",
"gender": "Ms",
"phone": "0101010101",
"phone2": "0606060606",
"birth_date": "1986-09-17",
"is_main": true
},
{
"reference": "contact_reference",
"email": "bob@proton.me",
"first_name": "Bob",
"last_name": "Morane",
"title": "Project Manager",
"gender": "Mr",
"phone": "0202020202",
"phone2": "0707070707",
"birth_date": "1985-10-18",
"is_main": false
}
],
"size": 2
},
"custom_fields": [
{
"name": "CustomField",
"value": "Value"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/client
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the client to retrieve |
Response
A JSON object containing the client information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the client |
| info_number | String | File number that appears in the client record. Not to be confused with reference |
| type | String | The type of the client (either "enterprise" or "individual") |
| company_name | String | Name of the client's company (if applicable) |
| info_notes | String | Notes on the client |
| website | String | Website of the client |
| vat_number | String | VAT number of the client (only for "enterprise" clients) |
| company_number | String | Company registration number of the client (only for "enterprise" clients) |
| predefined_net_margin_rate | Number | Predefined net margin rate in percentage (e.g., 15 for 15%). Leave blank '' if not set |
| user | JSON | JSON object representing the user (User) associated with the client |
| String | Email of the main contact at the client's organization | |
| first_name | String | First name of the main contact at the client's organization |
| last_name | String | Last name of the main contact at the client's organization |
| address | JSON | JSON object representing the address (Address) of the client |
| projects | JSON | Projects linked to the client (returns the first 10 projects) |
| contacts | Array | An array of JSON contacts (Contacts) associated with the client |
| custom_fields | Array | An array of JSON custom fields (Custom fields) for the client |
POST clients-upsert
This API endpoint updates a client record if the provided reference or email matches an existing client in your account. If no match is found, a new client record is created with the provided reference, or a randomly generated one if no reference is supplied. The client's email can be used as the primary key for upsert operations.
Duplicate Prevention Rules
- Enterprise clients: A client cannot be created or updated if another enterprise client already exists with the same company name.
- Individual clients: A client cannot be created or updated if another individual client already exists with the same first name, last name, and email.
Error messages
- Enterprise client duplication →
A client with this name already exists - Individual client duplication →
A client with this first name, last name and email already exists - Owner not found →
user must be the email of an active user of the account - Email ambiguity: if several clients in your account have a primary contact with the same email, the email cannot be used as a matching key. The request is rejected with an
AMBIGUOUS_EMAIL_REFERENCEerror and no record is updated or created. Use the client's unique reference instead.
curl --location 'https://api.ezus.app/clients-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data-raw '{
"reference": "client_reference",
"info_number": "202306001-C",
"type": "enterprise",
"company_name": "MOKE INTERNATIONAL LIMITED",
"website": "www.moke_ltd.com",
"vat_number": "FR 32 123456789",
"company_number": "362 521 879 00034",
"user": "sam@proton.me",
"contact": {
"mode": "upsert_main",
"email": "contact@moke-international.com",
"first_name": "Jane",
"last_name": "Doe",
"title": "CEO",
"gender": "Ms",
"phone": "0101010101",
"phone2": "0606060606",
"birth_date": "1986-09-17"
},
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
},
"custom_fields": [
{"name": "field_name", "value": "field_value"}
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "client_reference",
info_number: "202306001-C",
type: "enterprise",
company_name: "MOKE INTERNATIONAL LIMITED",
website: "www.moke_ltd.com",
vat_number: "FR 32 123456789",
company_number: "362 521 879 00034",
user: "sam@proton.me",
contact: {
mode: "upsert_main",
email: "contact@moke-international.com",
first_name: "Jane",
last_name: "Doe",
title: "CEO",
gender: "Ms",
phone: "0101010101",
phone2: "0606060606",
birth_date: "1986-09-17",
},
address: {
label: "58 Rue de Paradis",
city: "Paris",
country: "France",
zip: "75010",
geo: { x: 48.875761, y: 2.348727 },
},
custom_fields: [{ name: "field_name", value: "field_value" }],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/clients-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Client successfully created",
"reference": "client_reference"
}
HTTP Endpoint
POST https://api.ezus.app/clients-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | If provided, the unique reference associated with the client you want to update or create (or a random one will be generated). |
| mode | String | Optional. upsert (default) updates the client matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing client, by reference or by primary contact email. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. Nothing is created or updated when the call fails. |
| info_number | String | File number that appears in the client record. Not to be confused with reference |
| type | String | Optional parameter. Specifies the client type (enterprise or individual). If enterprise, company_name is required. If individual, provide contact.first_name or contact.last_name. |
| company_name | String | Required Name of the client's company (if applicable). If empty, the client will be considered an individual, and the name of the client will be the same as the name of the contact. |
| website | String | Website of the client |
| vat_number | String | VAT number of the client (only for "enterprise" clients) |
| company_number | String | Company registration number of the client (only for "enterprise" clients) |
| user | Email of an active Ezus user of your account, set as the owner of the client. An unknown email, or the email of a deleted or deactivated user, is rejected. | |
| contact | JSON | Main contact object (Contacts). Optional extra parameter mode in this endpoint. Mode values can either be: insert_main (default, creates and sets a main contact even if one exists) or upsert_main (updates the main contact if it exists, otherwise creates it) |
| address | JSON | JSON object address (Address) To reset the address, you can put '0'. Coordinates are optional: send geo with x (latitude, -90 to 90) and y (longitude, -180 to 180) to geolocate the address, with or without the other address fields; invalid coordinates are refused with the reason. An address sent without geo is stored as not geolocated and replaces any existing coordinates; an upsert without address leaves the address and its coordinates untouched. |
| custom_fields | Array | Array of JSON custom fields (Custom fields) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of client action was created |
| reference | String | The reference for the client, which you should store for future updates or retrievals |
Suppliers
GET suppliers
Returns a list of your suppliers, sorted by creation date from newest to oldest, with the most recent suppliers appearing first. The list of suppliers returned is paginated (50 per 50): to call the 50 next items in the list, call the route with the next_token query parameter.
curl --location 'https://api.ezus.app/suppliers' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/suppliers", headers);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "<NEXT_TOKEN>",
"size": 338,
"data_size": 50,
"page": 1,
"suppliers": [
{
"reference": "supplier_reference",
"info_number": "202306001-S",
"type": "accom, activity",
"company_name": "The best hotel",
"info_notes": "Emily confirmed: this hotel really is the best in town.",
"website": "www.the_best_hotel.com",
"capacity": "200",
"user": {
"email": "travel-design@e-corp.com",
"first_name": "Alice",
"last_name": "Tate",
"agency": "Paris Agency"
},
"destination": {
"reference": "destination_reference",
"name": "France",
"subdestination_reference": "subdestination_reference",
"subdestination_name": "Paris"
},
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
}
}
]
}
HTTP Endpoint
GET https://api.ezus.app/suppliers
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| next_token | String | Specify this parameter if you want to retrieve the following elements of a given list query. |
| reference | Dynamic filter | Filter on the supplier's reference. |
| company_name | Dynamic filter | Filter on the supplier's company_name. |
| info_number | Dynamic filter | Filter on the supplier's info_number. |
| destination_name | Dynamic filter | Filter on the supplier's destination.name. |
| subdestination_name | Dynamic filter | Filter on the supplier's destination.subdestination_name. |
| created_at | Dynamic date filter | Filter on the supplier creation date. |
| updated_at | Dynamic date filter | Filter on the supplier last update date. |
All filters are cumulative (AND): a supplier must match every supplied filter to be returned.
Response
A JSON object containing the supplier information with properties like:
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all suppliers have not been returned. Use it in another call to access the following suppliers |
| size | Number | The total number of suppliers available with these filters |
| data_size | Number | Number of suppliers returned on the current page |
| page | Number | The page number |
| suppliers | Array | An array of JSON objects, each representing a supplier. These objects are formatted according to a simplified version of the GET supplier response structure. (GET supplier) |
GET supplier
This API endpoint retrieves detailed information about a specific supplier in Ezus.
curl --location 'https://api.ezus.app/supplier?reference=supplier_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/supplier?reference=supplier_reference", headers);
This request returns a structured JSON object:
{
"error": "false",
"reference": "supplier_reference",
"info_number": "202306001-S",
"type": "accom, activity",
"company_name": "The best hotel",
"info_notes": "Emily confirmed: this hotel really is the best in town.",
"website": "www.the_best_hotel.com",
"capacity": "200",
"visual_url": "https://docs.google.com/presentation/d/10GoT7nVkSIScaHUQEPh-EyUms5o6D7bcgUYsJlyql94",
"user": {
"email": "travel-design@e-corp.com",
"first_name": "Alice",
"last_name": "Tate",
"agency": "Paris Agency"
},
"category": {
"reference": "category_reference",
"name": "Accommodation / Lodging",
"subcategory_reference": "subcategory_reference",
"subcategory_name": "Hotel Room"
},
"destination": {
"reference": "destination_reference",
"name": "France",
"subdestination_reference": "subdestination_reference",
"subdestination_name": "Paris"
},
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
},
"medias": {
"data": [
{
"media_name": "The lobby",
"path_full": "www.the_best_hotel.com/media/loby.jpg"
}
],
"size": 1
},
"products": {
"data": [
{
"reference": "product_reference",
"title": "2-bed room with breakfast"
}
],
"size": 1
},
"contacts": {
"data": [
{
"reference": "contact_reference",
"email": "contact@moke.com",
"first_name": "Jane",
"last_name": "Doe",
"title": "CEO",
"gender": "Ms",
"phone": "0101010101",
"phone2": "0606060606",
"is_main": true
},
{
"reference": "contact_reference",
"email": "bob@proton.me",
"first_name": "Bob",
"last_name": "Morane",
"title": "Project Manager",
"gender": "Mr",
"phone": "0202020202",
"phone2": "0707070707",
"is_main": false
}
],
"size": 2
},
"langs": [
{
"lang": "american",
"name": "The best hotel",
"short_description": "The best hotel: Parisian luxury redefined.",
"long_description": "Welcome to The best hotel, a luxurious Parisian hotel nestled in the heart of..."
},
{
"lang": "spanish",
"name": "The best hotel",
"short_description": "Luz y lujo en París: The best hotel.",
"long_description": "Bienvenido a The best hotel, un lujoso hotel parisino ubicado en el corazón de..."
}
],
"custom_fields": [
{
"name": "Stars",
"value": "5"
}
],
"tags": [
{
"reference": "mice",
"type": "supplier",
"name": "MICE"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/supplier
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the supplier to retrieve |
Response
A JSON object containing the supplier information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the supplier |
| info_number | String | File number that appears in the supplier record. Not to be confused with reference |
| type | String | 3 options: accom, activity, transport. A supplier can have no type, 1 type or several types. In this case, the different types are separated by commas |
| company_name | String | Name of the company of the supplier |
| info_notes | String | The notes about the product |
| website | String | Website of the supplier |
| capacity | String | Maximum number of people for which the supplier can be used |
| visual_url | String | URL of the Google Slides visual linked to the supplier |
| user | JSON | JSON object user (User) |
| category | JSON | JSON object category (Category) |
| destination | JSON | JSON object destination (Destination) |
| address | JSON | JSON object address (Address) |
| medias | JSON | JSON object medias (Medias) |
| products | JSON | JSON object products (Products) |
| contacts | Array | Array of JSON contacts (Contacts) |
| langs | Array | Array of JSON langs (Langs) |
| custom_fields | Array | Array of JSON custom fields (Custom fields) |
| tags | Array | Array of JSON tags (Tags) |
POST suppliers-upsert
It updates a supplier record if the provided reference (or the email) does match one of the supplier references in your account, otherwise it creates a new supplier record with the provided reference (or with a random one if no reference is provided). Note that for this endpoint, the email of the supplier can also be used as a primary key for the upsert.
Error messages
- Email ambiguity: if several suppliers in your account have a primary contact with the same email, the email cannot be used as a matching key. The request is rejected with an
AMBIGUOUS_EMAIL_REFERENCEerror and no record is updated or created. Use the supplier's unique reference instead.
curl --location 'https://api.ezus.app/suppliers-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data-raw '{
"reference": "supplier_reference",
"info_number": "202306001-S",
"type": "accom, activity",
"company_name": "The best hotel",
"website": "www.the_best_hotel.com",
"capacity": "200",
"user": "sam@proton.me",
"contact": {
"mode": "insert_main",
"email": "bob@proton.me",
"first_name": "Bob",
"last_name": "Morane",
"title": "Project Manager",
"gender": "Mr",
"phone": "0606060606",
"phone2": "0707070707"
},
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
},
"destination_reference": "destination_reference",
"subdestination_reference": "subdestination_reference",
"category_reference": "category_reference",
"subcategory_reference": "subdestination_reference",
"custom_fields": [
{"name": "field_name", "value": "field_value"}
],
"tags": ["tag_1", "tag_2", "tag_3"],
"langs": [
{
"lang": "french",
"name": "Mon fournisseur",
"short_description": "Une description courte en français",
"long_description": "Une description longue en français"
},
{
"lang": "american",
"name": "My supplier",
"short_description": "Short American Description",
"long_description": "Long American Description"
}
]
}
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "supplier_reference",
info_number: "202306001-S",
type: "accom, activity",
company_name: "The best hotel",
website: "www.the_best_hotel.com",
capacity: 200,
user: "sam@proton.me",
contact: {
mode: "insert_main",
email: "bob@proton.me",
first_name: "Bob",
last_name: "Morane",
title: "Project Manager",
gender: "Mr",
phone: "0606060606",
phone2: "0707070707",
},
address: {
label: "58 Rue de Paradis",
city: "Paris",
country: "France",
zip: "75010",
geo: { x: 48.875761, y: 2.348727 },
},
destination_reference: "destination_reference",
subdestination_reference: "subdestination_reference",
category_reference: "category_reference",
subcategory_reference: "subcategory_reference",
custom_fields: [{ name: "field_name", value: "field_value" }],
tags: ["tag_1", "tag_2", "tag_3"],
langs: [
{
lang: "french",
name: "Mon fournisseur",
short_description: "Une description courte en français",
long_description: "Une description longue en français",
},
{
lang: "american",
name: "My supplier",
short_description: "Short American Description",
long_description: "Long American Description",
},
],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/suppliers-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Supplier successfully created",
"reference": "supplier_reference"
}
HTTP Endpoint
POST https://api.ezus.app/suppliers-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | If provided, the unique reference associated to the supplier you want to update or create (in case the one you provided has never been used). If no reference is provided, a supplier will be created with a random one. |
| mode | String | Optional. upsert (default) updates the supplier matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing supplier, by reference or by primary contact email. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. Nothing is created or updated when the call fails. |
| info_number | String | File number that appears in the supplier record. Not to be confused with reference |
| type | String | Either undefined or a combination of these 3 options: accom, activity, transport. You can select multiple options by separating them with comas ("accom, activity" for instance). Enter "undefined" if you want to reset this parameter. |
| company_name | String | Required Name of the supplier. This parameter is required if you create a new supplier |
| website | String | Website of the supplier |
| capacity | Number | Maximum number of people for which the supplier can be used. Leave blank '' if not relevant |
| user | Email of the Ezus user that will be set as the owner of the supplier. By default, if no owner is provided or the provided email do not match any user on this account, the owner will be assigned to everyone | |
| contact | JSON | Main contact object (Contacts). Optional extra parameter mode in this endpoint. Mode values can either be: insert_main (default, creates and sets a main contact even if one exists) or upsert_main (updates the main contact if it exists, otherwise creates it). To reset the main contact, you can put '0' |
| address | JSON | JSON object address (Address) To reset the address, you can put '0'. Coordinates are optional: send geo with x (latitude, -90 to 90) and y (longitude, -180 to 180) to geolocate the address, with or without the other address fields; invalid coordinates are refused with the reason. An address sent without geo is stored as not geolocated and replaces any existing coordinates; an upsert without address leaves the address and its coordinates untouched. |
| destination_reference | String | Reference of the destination to link to the supplier. To reset the destination, you can put '0'. |
| subdestination_reference | String | Reference of the sub-destination to link to the supplier. To reset the sub-destination, you can put '0'. If the destination_reference is not provided, the subdestination_reference will be ignored. |
| category_reference | String | Reference of the category to link to the supplier. To reset the category, you can put '0'. |
| subcategory_reference | String | Reference of the sub-category to link to the supplier. To reset the sub-category, you can put '0'. If the category_reference is not provided, the subcategory_reference will be ignored. |
| custom_fields | Array | Array of JSON custom fields (Custom fields) |
| tags | Array | Array of strings representing tag technical names. If an empty array ([]) is provided, all existing product tags are removed. Otherwise, the provided tags fully replace the current ones. |
| langs | Array | Array of JSON langs representing the descriptions associated with this supplier. The specified language must be enabled for the given account (Langs) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of supplier action was created |
| reference | String | The reference for the supplier, which you should store for future updates or retrievals |
Products
GET products
Returns a list of your products, sorted by creation date from newest to oldest, with the most recent products appearing first. The list of products returned is paginated (50 per 50): to call the 50 next items in the list, call the route with the next_token query parameter. Call it with include=tariffs to also get the tariffs of each product, seasons included.
curl --location 'https://api.ezus.app/products' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/products", headers);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "<NEXT_TOKEN>",
"size": 338,
"data_size": 50,
"page": 1,
"products": [
{
"reference": "product_reference",
"info_number": "202306001-PR",
"title": "2-bed room with breakfast",
"capacity": "2",
"quantity": "1",
"currency": "EUR",
"vat_rate": 20.0,
"vat_regime": "margin",
"commission": {
"commission_mode": "purchase",
"commission_regime": "percent",
"value": "10"
},
"supplier_reference": "supplier_reference",
"package_reference": "package_reference",
"destination": {
"reference": "destination_reference",
"name": "France",
"subdestination_reference": "subdestination_reference",
"subdestination_name": "Paris"
},
"budget_form": "Important",
"budget_variable": "Display"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/products
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| next_token | String | Specify this parameter if you want to retrieve the following elements of a given list query. |
| include | String | Comma-separated list of objects to add to each product. Possible values: tariffs. The next_token keeps it for the next pages; any other value is refused with an error. |
| reference | Dynamic filter | Filter on the product's reference. |
| title | Dynamic filter | Filter on the product's title. |
| info_number | Dynamic filter | Filter on the product's info_number. |
| supplier_reference | Linked-record filter + Dynamic filter | Filter on the linked supplier's reference. |
| supplier_company_name | Linked-record filter + Dynamic filter | Filter on the linked supplier's company_name. |
| destination_name | Dynamic filter | Filter on the product's destination.name. |
| subdestination_name | Dynamic filter | Filter on the product's destination.subdestination_name. |
| created_at | Dynamic date filter | Filter on the product creation date. |
| updated_at | Dynamic date filter | Filter on the product last update date. |
All filters are cumulative (AND): a product must match every supplied filter to be returned.
Response
A JSON object containing the product information with properties like:
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all products have not been returned. Use it in another call to access the following products |
| size | Number | The total number of products available with these filters |
| data_size | Number | Number of products returned on the current page |
| page | Number | The page number |
| products | Array | An array of JSON objects, each representing a product. These objects are formatted according to a simplified version of the GET product response structure. (GET product). With include=tariffs, each product also carries its tariffs (Tariffs) |
GET product
This API endpoint retrieves detailed information about a specific product in Ezus.
curl --location 'https://api.ezus.app/product?reference=product_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/product?reference=product_reference", headers);
This request returns a structured JSON object:
{
"error": "false",
"reference": "product_reference",
"info_number": "202306001-PR",
"title": "2-bed room with breakfast",
"info_notes": "Product's notes",
"capacity": "2",
"quantity": "1",
"currency": "EUR",
"vat_rate": 20.0,
"vat_regime": "margin",
"visual_url": "https://docs.google.com/presentation/d/10GoT7nVkSIScaHUQEPh-EyUms5o6D7bcgUYsJlyql94",
"commission": {
"commission_mode": "purchase",
"commission_regime": "percent",
"value": "10"
},
"supplier": {
"reference": "supplier_reference",
"company_name": "The best hotel"
},
"package": {
"reference": "package_reference",
"title": "packages_title"
},
"category": {
"reference": "category_reference",
"name": "Accommodation / Lodging",
"subcategory_reference": "subcategory_reference",
"subcategory_name": "Hotel Room"
},
"destination": {
"reference": "destination_reference",
"name": "France",
"subdestination_reference": "subdestination_reference",
"subdestination_name": "Paris"
},
"budget_form": "Important",
"budget_text": "Option",
"budget_variable": "Display",
"medias": {
"data": [
{
"media_name": "img.jpeg",
"path_full": "https://link-img.jpeg"
}
],
"size": 1
},
"tariffs": [
{
"reference": "tariff_reference",
"type": "default",
"name": "",
"purchase_price": "100",
"margin_rate": "33.33",
"sales_price": "150",
"limit_start": "",
"limit_end": "",
"is_yearly": false,
"children": [
{
"reference": "",
"type": "custom",
"name": "",
"purchase_price": "100",
"margin_rate": "33.33",
"sales_price": "150",
"limit_start": "0",
"limit_end": "11",
"is_yearly": false
},
{
"reference": "",
"type": "custom",
"name": "",
"purchase_price": "100",
"margin_rate": "23.08",
"sales_price": "130",
"limit_start": "12",
"limit_end": "Infinity",
"is_yearly": false
}
]
},
{
"reference": "tariff_reference",
"type": "season",
"name": "",
"purchase_price": "100.0",
"margin_rate": "50.0",
"sales_price": "200.0",
"limit_start": "2026-05-01",
"limit_end": "2026-08-31",
"is_yearly": true,
"children": [
{
"reference": "",
"type": "custom",
"name": "",
"purchase_price": "100",
"margin_rate": "9.09",
"sales_price": "110",
"limit_start": "0",
"limit_end": "10",
"is_yearly": false
},
{
"reference": "",
"type": "custom",
"name": "",
"purchase_price": "100",
"margin_rate": "16.66",
"sales_price": "120",
"limit_start": "11",
"limit_end": "Infinity",
"is_yearly": false
}
]
}
],
"langs": [
{
"lang": "french",
"name": "Chambre à 2 lits avec petit déjeuner",
"short_description": "",
"long_description": ""
}
],
"custom_fields": [
{
"name": "View",
"value": "Parking"
}
],
"tags": [
{
"reference": "mice",
"type": "product",
"name": "MICE"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/product
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the product to retrieve |
Response
A JSON object containing the product information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the product |
| info_number | String | File number that appears in the product record. Not to be confused with reference |
| title | String | Name of the product |
| info_notes | String | Notes about your product |
| capacity | Number | Maximum number of people for which the product can be used |
| quantity | String | The default number for this product when it is added to a project. It can either be a Number or one of these letters (P = Number of people in the project, D = Number of days in the project, N = Number of nights in the project) |
| currency | String | The ISO 4217 currency code representing the currency you utilize (Link to doc) |
| vat_rate | Number | Default % of the VAT on the product |
| vat_regime | String | Can be either classic (common law VAT), margin (VAT on the margin), none (Non applicable VAT) |
| visual_url | String | URL of the Google Slides visual linked to the product |
| commission | JSON | A JSON object containing commission_mode ("sales" or "purchase"), commission_regime ("percent" or "amount"), value |
| supplier | JSON | A JSON object containing reference, company_name |
| package | JSON | A JSON object containing reference, title |
| category | JSON | JSON object category (Category) |
| destination | JSON | JSON object destination (Destination) |
| buget_form | String | Important, Normal, Low represent how the product will be highlight on the budget By Default |
| budget_text | String | This is an empty string "" if the product is not marked as an option in the budget, otherwise it is the custom label of the option to which the product is associated |
| budget_variable | String | Display, Do not Display, this option tells if the product will be displayed or not in the budget |
| medias | JSON | JSON object medias (Medias) |
| tariffs | Array | Array of JSON tariffs (Tariffs) |
| langs | Array | Array of JSON langs (Langs) |
| custom_fields | Array | Array of JSON custom fields (Custom fields) |
| tags | Array | Array of JSON tags (Tags) |
POST products-upsert
It updates a product record if the provided reference does match one of the product references in your account, otherwise it creates a new product record with the provided reference (or with a random one if no reference is provided).
curl --location 'https://api.ezus.app/products-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"reference": "product_reference",
"info_number": "202306001-PR",
"title": "2-bed room with breakfast",
"info_notes": "The notes about the product",
"capacity": "2",
"quantity": "1",
"currency": "USD",
"purchase_price": "42",
"sales_price": "84",
"vat_rate": 20,
"vat_regime": "none",
"commission": {
"commission_mode": "purchase",
"commission_regime": "percent",
"value": 10
},
"supplier_reference": "supplier_reference",
"package_reference": "package_reference",
"destination_reference": "destination_reference",
"subdestination_reference": "subdestination_reference",
"category_reference": "category_reference",
"subcategory_reference": "subcategory_reference",
"custom_fields": [
{"name": "field_name", "value": "field_value"}
],
"tags": ["tag_1", "tag_2", "tag_3"],
"langs": [
{
"lang": "french",
"name": "Mon produit",
"short_description": "Une description courte en français",
"long_description": "Une description longue en français"
},
{
"lang": "american",
"name": "My product",
"short_description": "Short American Description",
"long_description": "Long American Description"
}
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "product_reference",
info_number: "202306001-PR",
title: "2-bed room with breakfast",
info_notes: "Product's notes",
capacity: 2,
quantity: "1",
currency: "USD",
purchase_price: "42",
sales_price: "84",
vat_rate: "20",
vat_regime: "none",
commission: {
commission_mode: "purchase",
commission_regime: "percent",
value: "10",
},
supplier_reference: "supplier_reference",
package_reference: "package_reference",
destination_reference: "destination_reference",
subdestination_reference: "subdestination_reference",
category_reference: "category_reference",
subcategory_reference: "subcategory_reference",
custom_fields: [{ name: "field_name", value: "field_value" }],
tags: ["tag_1", "tag_2", "tag_3"],
langs: [
{
lang: "french",
name: "Mon produit",
short_description: "Une description courte en français",
long_description: "Une description longue en français",
},
{
lang: "american",
name: "My product",
short_description: "Short American Description",
long_description: "Long American Description",
},
],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/products-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Product successfully created",
"reference": "product_reference"
}
HTTP Endpoint
POST https://api.ezus.app/products-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | If provided, the unique reference associated to the product you want to update or create (in case the one you provided has never been used). If no reference is provided, a product will be created with a random one. |
| mode | String | Optional. upsert (default) updates the product matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing product. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. Nothing is created or updated when the call fails. |
| info_number | String | File number that appears in the product record. Not to be confused with reference |
| title | String | Title of your product. This parameter is required if you create a new product |
| info_notes | String | Notes about your product. This parameter is not required if you create or update a product |
| capacity | Number | Maximum number of people for which the product can be used. Leave blank '' if not relevant |
| quantity | String | The default number for this product when it is added to a project. It can either be a Number or one of these letters (P = Number of people in the project, D = Number of days in the project, N = Number of nights in the project) |
| currency | String | The ISO 4217 code of the currency of this product (Link to Doc). If empty or not provided, your default account currency will be set |
| purchase_price | Number | Purchase price as a number |
| sales_price | Number | Sales price as a number |
| vat_rate | Number | Default VAT rate. If empty or not provided, your default account VAT rate will be set |
| vat_regime | String | Can be either classic (common law VAT), margin (VAT on the margin), none (Non applicable VAT). If empty or not provided, your default account VAT regime will be set |
| commission | JSON | A JSON object containing commission_mode ("sales" or "purchase"), commission_regime ("percent" or "amount"), value |
| supplier_reference | String | If you give an adequate supplier reference, the product will be added in this supplier. If you want to update the supplier's product to None, you must enter 0. |
| package_reference | String | If you give an adequate package reference, the product will be added in this package. If you want to update the package's product to None, you must enter 0. |
| destination_reference | String | Reference of the destination to link to the product. To reset the destination, you can put '0'. |
| subdestination_reference | String | Reference of the sub-destination to link to the product. To reset the sub-destination, you can put '0'. If the destination_reference is not provided, the subdestination_reference will be ignored. |
| category_reference | String | Reference of the category to link to the product. To reset the category, you can put '0'. |
| subcategory_reference | String | Reference of the sub-category to link to the product. To reset the sub-category, you can put '0'. If the category_reference is not provided, the subcategory_reference will be ignored. |
| custom_fields | Array | Array of JSON custom fields (Custom fields) |
| tags | Array | Array of strings representing tag technical names. If an empty array ([]) is provided, all existing product tags are removed. Otherwise, the provided tags fully replace the current ones. |
| langs | Array | Array of JSON langs representing the descriptions associated with this product. The specified language must be enabled for the given account (Langs) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of product action was created |
| reference | String | The reference for the product, which you should store for future updates or retrievals |
POST product-seasons-upsert
Each update or insertion must reference an existing product via product_reference.
If the provided reference matches an existing seasonal tariff in your account, the record is updated; otherwise, a new seasonal tariff is created using the provided reference (or a randomly generated one if none is given).
curl --location 'https://api.ezus.app/product-seasons-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"product_reference": "product_reference",
"reference": "season_reference",
"name": "January 2026",
"purchase_price": 165.25,
"sales_price": 200,
"limit_start": "2026-01-01",
"limit_end": "2026-01-31",
"is_yearly": true
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
product_reference: "product_reference",
reference: "season_reference",
name: "January 2026",
purchase_price: 165.25,
sales_price: 200,
limit_start: "2026-01-01",
limit_end: "2026-01-31",
is_yearly: true,
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/product-seasons-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Season successfully created",
"reference": "season_reference"
}
HTTP Endpoint
POST https://api.ezus.app/product-seasons-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| product_reference | String | RequiredReference of the product for which you want to create or update a season. |
| reference | String | If provided, the unique reference associated to the season you want to update or create (in case the one you provided has never been used). If no reference is provided, a season will be created with a random one. |
| mode | String | Optional. upsert (default) updates the season matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing season. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. Nothing is created or updated when the call fails. |
| name | String | Name of the seasonal tariff (100 characters max). |
| purchase_price | Number | Purchase price (VAT included, in the product’s currency). Prices cannot be entered excluding VAT or in another currency. |
| sales_price | Number | Sales price (VAT included, in the product’s currency). Prices cannot be entered excluding VAT or in another currency. |
| limit_start | String | Start date of the season. "YYYY-MM-DD" format string |
| limit_end | String | End date of the season "YYYY-MM-DD" format string |
| is_yearly | Boolean | Indicates if the seasonal tariff recurs every year |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of product action was created |
| reference | String | The reference for the product, which you should store for future updates or retrievals |
PUT product-tariffs-levels-replace
Replaces the whole grid of quantity levels of one tariff of a product: its default tariff or one of its seasons. The grid sent replaces the stored levels in one operation. An invalid grid is refused as a whole, and the stored grid stays unchanged.
curl --location --request PUT 'https://api.ezus.app/product-tariffs-levels-replace' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data-raw '{
"product_reference": "product_reference",
"tariff_reference": "tariff_reference",
"levels": [
{"limit_start": 0, "limit_end": 3, "purchase_price": 78, "sales_price": 145},
{"limit_start": 4, "limit_end": "Infinity", "purchase_price": 90, "sales_price": 135}
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
product_reference: "product_reference",
tariff_reference: "tariff_reference",
levels: [
{ limit_start: 0, limit_end: 3, purchase_price: 78, sales_price: 145 },
{
limit_start: 4,
limit_end: "Infinity",
purchase_price: 90,
sales_price: 135,
},
],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.put(baseUrl + "/product-tariffs-levels-replace", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"product_reference": "product_reference"
}
HTTP Endpoint
PUT https://api.ezus.app/product-tariffs-levels-replace
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| product_reference | String | Required Reference of the product |
| tariff_reference | String | Required Reference of the default tariff or of a season of the product (reference in Tariffs). A level's reference is refused |
| levels | Array | Required The whole grid, ordered by quantity. An empty array removes every level: the tariff's own price applies again |
| levels[].limit_start | Integer | Required First quantity of the level. The first level starts at 0, each next level right after the limit_end of the previous one |
| levels[].limit_end | Integer or String | Required Last quantity of the level, included. "Infinity" on the last level, and only there |
| levels[].purchase_price | Number | Required Purchase price (VAT included, in the product’s currency) |
| levels[].sales_price | Number | Required Sales price (VAT included, in the product’s currency) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| product_reference | String | Reference of the product whose levels were replaced |
Packages
GET package
This API endpoint retrieves detailed information about a specific package in Ezus.
curl --location 'https://api.ezus.app/package?reference=package_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/package?reference=package_reference", headers);
This request returns a structured JSON object:
{
"error": "false",
"reference": "package_reference",
"info_number": "202306001-PK",
"title": "The best package",
"info_notes": "A classical day in Paris",
"capacity": "2",
"visual_url": "https://docs.google.com/presentation/d/10GoT7nVkSIScaHUQEPh-EyUms5o6D7bcgUYsJlyql94",
"suppliers": {
"data": [
{
"reference": "supplier_reference",
"company_name": "The best hotel"
}
],
"size": 1
},
"medias": {
"data": [],
"size": 0
},
"products": {
"data": [
{
"reference": "product_reference",
"title": "2-bed room with breakfast"
},
{
"reference": "product_reference_1235",
"title": "A gourmet menu for 2"
}
],
"size": 2
},
"langs": [
{
"lang": "american",
"name": "The best package",
"short_description": "A classical day in Paris",
"long_description": "Immerse yourself in the romance and elegance of a classical Parisian day, as our hotel and restaurant capture the essence of this magical city."
},
{
"lang": "french",
"name": "Le meilleur package",
"short_description": "Une journée classique à Paris",
"long_description": "Plongez dans le romantisme et l'élégance d'une journée parisienne classique, car notre hôtel et notre restaurant capturent l'essence de cette ville magique."
}
],
"custom_fields": [
{
"name": "Is for children?",
"value": "False"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/package
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the package to retrieve |
Response
A JSON object containing the package information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the package |
| info_number | String | File number that appears in the package record. Not to be confused with reference |
| title | String | Name of the package |
| info_notes | String | Notes on the package |
| capacity | String | Maximum number of people for which the package can be used |
| visual_url | String | URL of the Google Slides visual linked to the package |
| suppliers | JSON | JSON object suppliers (Suppliers) |
| medias | JSON | JSON object medias (Medias) |
| products | JSON | JSON object products (Products) |
| langs | Array | Array of JSON langs (Langs) |
| custom_fields | Array | Array of JSON custom fields Custom fields |
POST packages-upsert
It updates a package record if the provided reference does match one of the package references in your account, otherwise it creates a new package record with the provided reference (or with a random one if no reference is provided).
curl --location 'https://api.ezus.app/packages-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"reference": "package_reference",
"info_number": "202306001-PK",
"title": "The best package",
"capacity": "2",
"destination_reference": "destination_reference",
"subdestination_reference": "subdestination_reference",
"category_reference": "category_reference",
"subcategory_reference": "subcategory_reference",
"custom_fields": [
{"name": "field_name", "value": "field_value"}
],
"langs": [
{
"lang": "french",
"name": "Mon package",
"short_description": "Une description courte en français",
"long_description": "Une description longue en français"
},
{
"lang": "american",
"name": "My package",
"short_description": "Short American Description",
"long_description": "Long American Description"
}
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "package_reference",
info_number: "202306001-PK",
title: "The best package",
capacity: "2",
destination_reference: "destination_reference",
subdestination_reference: "subdestination_reference",
category_reference: "category_reference",
subcategory_reference: "subcategory_reference",
custom_fields: [{ name: "field_name", value: "field_value" }],
langs: [
{
lang: "french",
name: "Mon package",
short_description: "Une description courte en français",
long_description: "Une description longue en français",
},
{
lang: "american",
name: "My package",
short_description: "Short American Description",
long_description: "Long American Description",
},
],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/packages-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Package successfully created",
"reference": "package_reference"
}
HTTP Endpoint
POST https://api.ezus.app/packages-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | If provided, the unique reference associated to the package you want to update or create (in case the one you provided has never been used). If no reference is provided, a package will be created with a random one. |
| mode | String | Optional. upsert (default) updates the package matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing package. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. Nothing is created or updated when the call fails. |
| info_number | String | File number that appears in the package record. Not to be confused with reference |
| title | String | This parameter is required if you create a new package |
| capacity | Number | Maximum number of people for which the package can be used . Leave blank '' if not relevant |
| destination_reference | String | Reference of the destination to link to the package. To reset the destination, you can put '0'. |
| subdestination_reference | String | Reference of the sub-destination to link to the package. To reset the sub-destination, you can put '0'. If the destination_reference is not provided, the subdestination_reference will be ignored. |
| category_reference | String | Reference of the category to link to the package. To reset the category, you can put '0'. |
| subcategory_reference | String | Reference of the sub-category to link to the package. To reset the sub-category, you can put '0'. If the category_reference is not provided, the subcategory_reference will be ignored. |
| custom_fields | Array | Array of JSON custom fields Custom fields |
| langs | Array | Array of JSON langs representing the descriptions associated with this package. The specified language must be enabled for the given account (Langs) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of package action was created |
| reference | String | The reference for the package, which you should store for future updates or retrievals |
Categories
GET categories
Returns a list of all categories and sub-categories. The list is not paginated and is theoretically limited to 1000 objects (categories and sub-categories), although higher limits may work depending on the payload size. The order of the categories and sub-categories matches their order in Ezus.
curl --location 'https://api.ezus.app/categories' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/categories", headers);
This request returns a structured JSON object:
{
"error": "false",
"size": 1,
"categories": [
{
"reference": "category_reference",
"name": "Experiences",
"subcategories": [
{
"reference": "subcategory_reference",
"name": "Relaxation"
}
]
}
]
}
HTTP Endpoint
GET https://api.ezus.app/categories
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Response
A JSON object containing the category information, with properties like:
| Property | Type | Description |
|---|---|---|
| size | Number | The total number of categories |
| categories | Array | Array of JSON categories (Categories) |
Destinations
GET destinations
Returns a list of all destinations and sub-destinations. The list is not paginated and is theoretically limited to 1000 objects (destinations and sub-destinations), although higher limits may work depending on the payload size. The order of the destinations and sub-destinations matches their order in Ezus.
curl --location 'https://api.ezus.app/destinations' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/destinations", headers);
This request returns a structured JSON object:
{
"error": "false",
"size": 32,
"destinations": [
{
"reference": "destination_reference",
"name": "France",
"subdestinations": [
{
"reference": "subdestination_reference",
"name": "Paris"
}
],
"langs": [
{
"lang": "french",
"name": "Un pays intéressant"
}
]
}
]
}
HTTP Endpoint
GET https://api.ezus.app/destinations
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Response
A JSON object containing the destination information with properties like:
| Property | Type | Description |
|---|---|---|
| size | Number | The total number of destinations |
| destinations | Array | Array of JSON destinations (Destinations) |
POST destinations-upsert
It updates a destination record if the provided reference does match one of the destination references in your account, otherwise it creates a new destination record with the provided reference (or with a random one if no reference is provided).
curl --location 'https://api.ezus.app/destinations-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
--data '{
"reference": "destination_reference",
"name": "France",
"langs": [
{
"lang": "french",
"name": "Ma destination"
},
{
"lang": "american",
"name": "My destination"
}
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "destination_reference",
name: "France",
langs: [
{
lang: "french",
name: "Ma destination",
},
{
lang: "american",
name: "My destination",
},
],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/destinations-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Destination successfully created",
"reference": "destination_reference"
}
HTTP Endpoint
POST https://api.ezus.app/destinations-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | If provided, the unique reference associated to the destination you want to update or create (in case the one you provided has never been used). If no reference is provided, a destination will be created with a random one. |
| mode | String | Optional. upsert (default) updates the destination matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing destination. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. Nothing is created or updated when the call fails. |
| name | String | This parameter is required. Name of the destination to create or update. If a destination already exists with this name, it will return an error. |
| langs | Array | Array of JSON langs representing the descriptions associated with this destination. The specified language must be enabled for the given account (Langs) - only name supported in this case. |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of destination action was created |
| reference | String | The reference for the destination, which you should store for future updates or retrievals |
GET subdestination
This API endpoint retrieves detailed information about a specific sub-destination in Ezus.
curl --location 'https://api.ezus.app/subdestination?reference=subdestination_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(
baseUrl + "/subdestination?reference=subdestination_reference",
headers
);
This request returns a structured JSON object:
{
"error": "false",
"reference": "subdestination_reference",
"name": "Paris",
"destination_reference": "destination_reference",
"destination_name": "France",
"visual_url": "https://docs.google.com/presentation/d/10GoT7nVkSIScaHUQEPh-EyUms5o6D7bcgUYsJlyql94",
"medias": {
"data": [
{
"media_name": "img.jpeg",
"path_full": "https://link-img.jpeg"
}
],
"size": 1
},
"langs": [
{
"lang": "french",
"name": "Chambre à 2 lits avec petit déjeuner",
"short_description": "",
"long_description": ""
}
]
}
HTTP Endpoint
GET https://api.ezus.app/subdestination
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | The reference of the sub-destination |
Response
A JSON object containing the sub-destination information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the sub-destination |
| name | String | Name of the sub-destination |
| destination_reference | String | The reference of the destination |
| destination_name | String | Name of the destination |
| visual_url | String | URL of the Google Slides visual linked to the sub-destination |
| medias | JSON | JSON object medias (Medias) |
| langs | Array | Array of JSON langs (Langs) |
POST subdestinations-upsert
It updates a sub-destination record if the provided reference does match one of the sub-destination references in your account, otherwise it creates a new sub-destination record with the provided reference (or with a random one if no reference is provided).
curl --location 'https://api.ezus.app/subdestinations-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
--data '{
"reference": "subdestination_reference",
"destination_reference": "destination_reference",
"name": "Paris",
"langs": [
{
"lang": "french",
"name": "Ma sous-destination",
"short_description": "Une description courte en français",
"long_description": "Une description longue en français"
},
{
"lang": "american",
"name": "My sub-destination",
"short_description": "Short American Description",
"long_description": "Long American Description"
}
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "subdestination_reference",
destination_reference: "destination_reference"
name: "Paris",
langs: [
{
lang: "french",
name: "Ma sous-destination",
short_description: "Une description courte en français",
long_description: "Une description longue en français",
},
{
lang: "american",
name: "My sub-destination",
short_description: "Short American Description",
long_description: "Long American Description",
},
],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/subdestinations-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Subdestination successfully created",
"reference": "subdestination_reference"
}
HTTP Endpoint
POST https://api.ezus.app/subdestinations-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | If provided, the unique reference associated to the sub-destination you want to update or create (in case the one you provided has never been used). If no reference is provided, a sub-destination will be created with a random one. |
| mode | String | Optional. upsert (default) updates the sub-destination matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing sub-destination. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. Nothing is created or updated when the call fails. |
| destination_reference | String | This parameter is required and must match an existing destination. |
| name | String | This parameter is required. Name of the sub-destination to create or update. If a sub-destination already exists with this name, it will return an error. |
| langs | Array | Array of JSON langs representing the descriptions associated with this sub-destination. The specified language must be enabled for the given account (Langs) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of sub-destination action was created |
| reference | String | The reference for the sub-destination, which you should store for future updates or retrievals |
Invoices
GET invoices
Returns a list of your invoices, sorted by creation date from newest to oldest, with the most recent invoices appearing first. You can specify filters as query parameters to narrow down your search. The list of invoices returned is paginated (50 per 50): to call the 50 next items in the list, call the route with the next_token query parameter.
curl --location 'https://api.ezus.app/invoices?stage=completed' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/invoices?stage=completed", headers);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "<NEXT_TOKEN>",
"size": 338,
"data_size": 50,
"page": 1,
"invoices": [
{
"error": "false",
"reference": "invoice_reference",
"info_number": "2023_101010",
"type": "credit_note",
"origin_reference": "origin_reference",
"origin_info_number": "2023_101009",
"stage": "completed",
"created_date": "2023-10-10",
"send_date": "2023-10-10",
"due_date": "2023-10-10",
"currency": "EUR",
"is_einvoice_ready": true,
"amount_ttc": 1200.0,
"amount_ht": 1000.0,
"vat": 200.0,
"project": {
"reference": "project_reference",
"info_number": "202306001-P",
"info_title": "Paris fashion week 2024",
"info_stage_reference": "confirmed",
"info_stage": "Confirmed",
"currency": "EUR",
"is_closed": false
},
"alternative": {
"sort_order": "0",
"title": "Main Alternative",
"trip_date_in": "2024-03-01",
"trip_date_out": "2024-03-09",
"trip_duration": 9
},
"client": {
"reference": "client_reference",
"type": "enterprise",
"company_name": "MOKE INTERNATIONAL LIMITED",
"first_name": "Jane",
"last_name": "Doe",
"email": "contact@moke-international.com"
},
"forecast": {
"is_automatic": true,
"purchase": 0.0,
"commission": 0.0,
"vat_deducted": 0.0,
"amount_ht": 1000.0
},
"actual": {
"is_automatic": true,
"purchase": null,
"commission": null,
"vat_deducted": null,
"amount_ht": null
},
"url": "https://ezus.io/2023_101010.pdf"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/invoices
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| next_token | String | Specify this parameter if you want to retrieve the following elements of a given list query. If this parameter is filled, other parameters are ignored. |
| stage | String | You can filter invoices that are at a specific stage. The stage can be paid, completed or draft. |
| is_einvoice_ready | Boolean | Filter invoices ready for e-invoicing. Accepts true or false. |
| client_reference | Linked-record filter | Exact match. Filter invoices by the reference of the linked client. |
| project_info_stage_reference | Linked-record filter | Exact match. Filter invoices whose linked project is at a given stage... |
| technical_name | String | You can filter invoices according to one of their custom fields by adding the technical_name of the custom field as a query parameter and the desired value as a value. |
| info_number | Dynamic filter | Filter on the invoice's info_number. |
| project_info_number | Linked-record filter + Dynamic filter | Filter on the linked project's info_number. |
| created_date | Dynamic date filter | Filter on the invoice creation date. |
| send_date | Dynamic date filter | Filter on the invoice send date. |
| due_date | Dynamic date filter | Filter on the invoice due date. |
| alternative_trip_date_in | Linked-record filter + Dynamic date filter | Filter on the linked alternative's trip start date. |
| alternative_trip_date_out | Linked-record filter + Dynamic date filter | Filter on the linked alternative's trip end date. |
All filters are cumulative (AND): an invoice must match every supplied filter to be returned.
Response
A JSON object containing the invoice information with properties like:
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all invoices have not been returned. Use it in another call to access the following invoices |
| size | Number | The total number of invoices available with these filters |
| data_size | Number | Number of invoices returned on the current page |
| page | Number | The page number |
| invoices | Array | An array of JSON objects, each representing a invoice. These objects are formatted according to a simplified version of the GET invoice response structure. (GET invoice) |
GET invoice
This API endpoint retrieves detailed information about a specific invoice in Ezus.
curl --location 'https://api.ezus.app/invoice?reference=invoice_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/invoice?reference=invoice_reference", headers);
This request returns a structured JSON object:
{
"error": "false",
"reference": "invoice_reference",
"info_number": "2023_101010",
"type": "credit_note",
"origin_reference": "origin_reference",
"origin_info_number": "2023_101009",
"stage": "draft",
"created_date": "2023-10-10",
"send_date": "2023-10-10",
"due_date": "2023-10-10",
"currency": "EUR",
"is_einvoice_ready": true,
"amount_ttc": 1200.0,
"amount_ht": 1000.0,
"vat": 200.0,
"url": "https://ezus.io/2023_101010.pdf",
"project": {
"reference": "project_reference",
"info_number": "202306001-P",
"info_title": "Paris fashion week 2024",
"info_stage_reference": "confirmed",
"info_stage": "Confirmed",
"currency": "EUR",
"is_closed": false
},
"alternative": {
"sort_order": "0",
"title": "Main Alternative",
"trip_date_in": "2024-03-01",
"trip_date_out": "2024-03-09",
"trip_duration": 9
},
"client": {
"reference": "client_reference",
"type": "enterprise",
"company_name": "MOKE INTERNATIONAL LIMITED",
"first_name": "Jane",
"last_name": "Doe",
"email": "contact@moke-international.com"
},
"forecast": {
"is_automatic": true,
"purchase": 0.0,
"commission": 0.0,
"vat_deducted": 0.0,
"amount_ht": 1000.0
},
"actual": {
"is_automatic": true,
"purchase": null,
"commission": null,
"vat_deducted": null,
"amount_ht": null
},
"lines": [
{
"title": "Private Suite at Hôtel Ritz Paris",
"quantity": 1,
"price": 1200,
"price_excl_taxes": 1000,
"description": "Luxury private suite accommodation at Hôtel Ritz Paris including premium amenities and concierge services.",
"tax_rate": 20,
"tax_regime": {
"name": "classic",
"category": "S",
"comment": ""
}
}
]
}
HTTP Endpoint
GET https://api.ezus.app/invoice
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the invoice to retrieve |
Response
A JSON object containing the invoice information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the invoice |
| info_number | String | Title of the invoice |
| type | String | Type of the invoice invoice or credit_note |
| origin_reference | String | This is only displayed if the type of the invoice is a credit_note. The reference of the origin invoice. |
| origin_info_number | String | This is only displayed if the type of the invoice is a credit_note. Title of the origin invoice. |
| stage | String | Stage of the invoice draft completed or paid |
| created_date | String | Date of the creation of this invoice, in a "YYYY-MM-DD" format |
| send_date | String | Sent date of this invoice, in a "YYYY-MM-DD" format |
| due_date | String | Due date of this invoice, in a "YYYY-MM-DD" format |
| currency | String | The ISO 4217 currency code representing the currency you utilize (Link to doc) |
| is_einvoice_ready | Boolean | Is the invoice ready for e-invoicing |
| amount_ttc | Number | Amount of the invoice including taxes |
| amount_ht | Number | Amount of the invoice excluding taxes |
| vat | Number | VAT amount of the invoice |
| url | String | URL of the invoice .pdf file |
| project | JSON | JSON including: reference, info_number, info_title, info_stage_reference, info_stage, currency and is_closed |
| alternative | JSON | JSON including: sort_order, title, trip_date_in, trip_date_out and trip_duration |
| client | JSON | JSON including: reference, type (enterprise or individual), company_name, first_name, last_name and email |
| forecast | JSON | JSON object forecast (Invoices Amounts) |
| actual | JSON | JSON object actual (Invoices Amounts) |
| lines | Array | Array of JSON invoices lines (Invoices Lines) |
PUT invoices-update
It updates an invoice record if the provided reference does match one of the invoices references in your account.
curl --location --request PUT 'https://api.ezus.app/invoices-update' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data-raw '{
"reference": "invoice_reference",
"stage": "paid",
"due_date": "2023-09-29",
"custom_fields": [
{"name": "field_name", "value": "field_value"}
]
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "invoice_reference",
stage: "paid",
due_date: "2023-09-29",
custom_fields: [{ name: "field_name", value: "field_value" }],
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.put(baseUrl + "/invoices-update", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Invoice successfully updated",
"reference": "invoice_reference"
}
HTTP Endpoint
PUT https://api.ezus.app/invoices-update
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | The reference of the invoice you want to update |
| stage | String | Represents the stage of the invoice. Allowed updates: you can move from draft to paid or completed. Once set to paid or completed, switching between these stages is allowed. Reverting back to draft is not permitted |
| due_date | String | due_date can be updated only if the invoice is a draft, due_date can be only on format YYYY-MM-DD |
| custom_fields | Array | Array of JSON custom fields (Custom fields) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
Please note that invoice finalization (the step that occurs when moving an invoice from the draft stage to paid or completed) can occasionally be busy if another finalization is already in progress.
In such cases, the response message will indicate that the process is busy, and the client simply needs to retry the request after a short delay.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of invoice action was created |
| reference | String | The reference for the invoice, which you should store for future updates or retrievals |
GET invoices-supplier
This API endpoint retrieves a list of purchase invoices in Ezus.
curl --location 'https://api.ezus.app/invoices-supplier' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/invoices-supplier", headers);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "<NEXT_TOKEN>",
"size": 1240,
"data_size": 50,
"page": 1,
"invoices-supplier": [
{
"reference": "invoice_supplier_reference",
"has_attachement": true,
"filename": "2023_101010.pdf",
"url": "https://ezus.io/2023_101010.pdf",
"created_date": "2023-10-10",
"due_date": "2023-10-10",
"send_date": "2023-10-10",
"currency": "EUR",
"amount_ttc": 160.0,
"amount_ht": 120.0,
"vat": 40.0,
"supplier_reference": "supplier_reference",
"project_reference": "project_reference",
"alternative_order": "0",
"paid": 150.0
}
]
}
HTTP Endpoint
GET https://api.ezus.app/invoices-supplier
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| next_token | String | Specify this parameter if you want to retrieve the following elements of a given list query. If this parameter is filled, other parameters are ignored. |
| has_attachement | Boolean | true if a file is attached (filename and url are both set), false otherwise |
| supplier_reference | String | Filter invoices by the given supplier reference |
| project_reference | String | Filter invoices by the given project reference |
| alternative_order | Number | If project_reference is not provided, this parameter is ignored and the query applies to all alternatives of all projects.If project_reference is provided, alternative_order must be a non-negative number: 0 targets the main alternative and the value falls back to 0 if not specified. |
Response
A JSON object containing the invoices-supplier information with properties like:
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all invoices have not been returned. Use it in another call to access the following invoices |
| size | Number | The total number of invoices available with these filters |
| data_size | Number | Number of invoices returned on the current page |
| page | Number | The page number |
| invoices-supplier | Array | An array of JSON objects, each representing an invoice-supplier. These objects are formatted according to a simplified version of the GET invoice-supplier response structure. (GET invoice-supplier) |
Each invoice-supplier of the invoices-supplier list is a JSON object containing the invoice-supplier information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the supplier invoice |
| has_attachement | Boolean | true if a file is attached (filename and url are both set), false otherwise |
| filename | String | Filename of the supplier invoice |
| url | String | URL of the supplier invoice file |
| created_date | String | Date of the creation of the supplier invoice, in a "YYYY-MM-DD" format |
| due_date | String | Due date of the supplier invoice, in a "YYYY-MM-DD" format |
| send_date | String | Sent date of the supplier invoice, in a "YYYY-MM-DD" format |
| currency | String | The ISO 4217 currency code representing the currency you utilize (Link to doc) |
| amount_ttc | Number | Amount of the supplier invoice including taxes |
| amount_ht | Number | Amount of the supplier invoice excluding taxes |
| vat | Number | VAT amount of the supplier invoice |
| supplier_reference | String | Reference of the related supplier, or an empty string if no supplier is assigned |
| project_reference | String | Reference of the related project |
| alternative_order | Number | Reference of the related alternative order; 0 is for main alternative |
| paid | Number | Sum of the payments already made on the invoice |
GET invoice-supplier
This API endpoint retrieves detailed information about a specific purchase invoice in Ezus.
curl --location 'https://api.ezus.app/invoice-supplier?reference=invoice_supplier_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(
baseUrl + "/invoice-supplier?reference=invoice_supplier_reference",
headers
);
This request returns a structured JSON object:
{
"error": "false",
"reference": "invoice_supplier_reference",
"has_attachement": true,
"filename": "File Name",
"url": "https://ezus.io/2023_101010.pdf",
"created_date": "2023-10-10",
"due_date": "2023-10-20",
"send_date": "2023-10-15",
"currency": "EUR",
"amount_ttc": 1200.0,
"amount_ht": 1000.0,
"vat": 200.0,
"supplier": {
"reference": "supplier_reference",
"company_name": "The best hotel",
"website": "www.the_best_hotel.com"
},
"project": {
"reference": "project_reference",
"info_number": "202306001-P",
"info_title": "Paris fashion week 2024",
"info_stage_reference": "confirmed",
"info_stage": "Confirmed",
"currency": "EUR",
"is_closed": false
},
"alternative": {
"sort_order": "0",
"title": "Main Alternative"
},
"client": {
"reference": "client_reference",
"type": "enterprise",
"company_name": "MOKE INTERNATIONAL LIMITED",
"first_name": "Jane",
"last_name": "Doe",
"email": "contact@moke-international.com"
},
"payments": [
{
"reference": "payment_reference",
"date": "2023-10-10",
"amount": 500.0,
"payment_method": "Credit Card"
},
{
"reference": "payment_reference",
"date": "2023-10-11",
"amount": 500.0,
"payment_method": "Wire"
},
{
"reference": "payment_reference",
"date": "2023-10-12",
"amount": 200.0,
"payment_method": "Check"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/invoice-supplier
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| reference | String | Required The reference of the invoice to retrieve |
Response
A JSON object containing the supplier invoice information with properties like:
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the supplier invoice |
| has_attachement | Boolean | true if a file is attached (filename and url are both set), false otherwise |
| filename | String | Filename of the supplier invoice |
| url | String | URL of the supplier invoice file |
| created_date | String | Date of the creation of the supplier invoice, in a "YYYY-MM-DD" format |
| due_date | String | Due date of the supplier invoice, in a "YYYY-MM-DD" format |
| send_date | String | Sent date of the supplier invoice, in a "YYYY-MM-DD" format |
| currency | String | The ISO 4217 currency code representing the currency you utilize (Link to doc) |
| amount_ttc | Number | Amount of the supplier invoice including taxes |
| amount_ht | Number | Amount of the supplier invoice excluding taxes |
| vat | Number | VAT amount of the supplier invoice |
| supplier | JSON | JSON including: reference, company_name and website |
| project | JSON | JSON including: reference, info_title, info_stage, info_stage_reference, info_number, currency and is_closed |
| alternative | JSON | JSON including: sort_order and title |
| client | JSON | JSON including: reference, type (enterprise or individual), company_name, first_name, last_name and email |
| payments | Array | Array of JSON including: reference, date, amount and payment_method |
POST invoices-supplier-upsert
This endpoint allows you to create or update a supplier invoice (purchase invoice) on a project.
The endpoint works in upsert mode: if the provided reference matches an existing, non-deleted supplier invoice of your account that belongs to the specified supplier and project, the invoice is updated. Otherwise, a new supplier invoice is created.
curl --location 'https://api.ezus.app/invoices-supplier-upsert' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"supplier_reference": "supplier_reference",
"project_reference": "project_reference",
"alternative_order": "0",
"reference": "invoice_supplier_reference",
"due_date": "2023-10-20",
"amount_ttc": 1200.00,
"amount_ht": 1000.00,
"filename": "2023_101010.pdf",
"url": "https://ezus.io/2023_101010.pdf",
"note": "Invoice for the Paris fashion week 2024 project"
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
supplier_reference: "supplier_reference",
project_reference: "project_reference",
alternative_order: "0",
reference: "invoice_supplier_reference",
due_date: "2023-10-20",
amount_ttc: 1200.0,
amount_ht: 1000.0,
filename: "2023_101010.pdf",
url: "https://ezus.io/2023_101010.pdf",
note: "Invoice for the Paris fashion week 2024 project",
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/invoices-supplier-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Supplier invoice successfully created",
"reference": "invoice_supplier_reference"
}
HTTP Endpoint
POST https://api.ezus.app/invoices-supplier-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| supplier_reference | String | Required Reference of the supplier the invoice belongs to. Must match a valid, non-deleted supplier of the specified project. |
| project_reference | String | Required Reference of the project the invoice belongs to. Must match a valid, non-deleted project of your account. |
| alternative_order | String | Alternative number. If not provided, the invoice is attached to the project's main alternative (0). |
| reference | String | Unique reference of the supplier invoice to create or update. If not provided, a UUID v4 is automatically generated and returned. Must be less than 100 characters, otherwise an error is returned. |
| mode | String | Optional. upsert (default) updates the supplier invoice matching reference, or creates it when none matches. create fails with a REFERENCE_ALREADY_EXISTS error when reference matches an existing supplier invoice. update requires reference and fails with a REFERENCE_NOT_FOUND error when none matches. Nothing is created or updated when the call fails. |
| due_date | String | Due date of the supplier invoice, in a "YYYY-MM-DD" format. |
| amount_ttc | Number | Amount of the supplier invoice including taxes. |
| amount_ht | Number | Amount of the supplier invoice excluding taxes. |
| filename | String | Name associated to the invoice file (PDF). Optional. If left empty while url is provided, the filename is deduced from the downloaded file. |
| url | String | Link to the invoice file. Only .pdf files are accepted. Required if filename is provided, otherwise an error is returned. If provided while filename is empty, the filename is deduced from the downloaded file. |
| note | String | Note attached to the supplier invoice. |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Summary of the action performed (e.g., "Supplier invoice successfully created" or "Supplier invoice successfully updated") |
| reference | String | Reference of the supplier invoice that was created or updated (the auto-generated UUID on insert, or the provided reference otherwise) |
Currency
- The currency of the supplier invoice is the currency of the project it is inserted into (V1).
- If the supplier (
project_supplier) has a currency different from the project's currency, an error is returned (this case is not handled in V1).
POST invoices-supplier-payments-create
This endpoint allows you to create a payment attached to an existing supplier invoice (purchase invoice).
The endpoint works in creation mode only: payments cannot be updated or deleted through the public API. If the provided reference is already used by a payment of your account, an error is returned.
curl --location 'https://api.ezus.app/invoices-supplier-payments-create' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"invoice_supplier_reference": "invoice_supplier_reference",
"reference": "payment_reference",
"date": "2026-05-28",
"amount": 600.00,
"payment_method": "default4"
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
invoice_supplier_reference: "invoice_supplier_reference",
reference: "payment_reference",
date: "2026-05-28",
amount: 600.0,
payment_method: "default4",
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/invoices-supplier-payments-create", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Supplier invoice payment successfully created",
"reference": "payment_reference"
}
HTTP Endpoint
POST https://api.ezus.app/invoices-supplier-payments-create
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| invoice_supplier_reference | String | Required Reference of the supplier invoice the payment is attached to. Must match a valid, non-deleted supplier invoice of your account, otherwise an error is returned. |
| reference | String | Unique reference of the payment to create. If not provided, a UUID v4 is automatically generated and returned. Must be less than 36 characters and not already used by a payment of your account, otherwise an error is returned. |
| date | String | Required Date of the payment, in a "YYYY-MM-DD" format. Must be a date between years 2000 and 2050 (exclusive), otherwise an error is returned. |
| amount | Number | Required Amount of the payment. The value is rounded to 2 decimals before being stored. If the provided value is not a number, an error is returned. |
| payment_method | String | Technical name of the payment method (e.g. "default4"). If the provided value does not match any payment method of your account, an error is returned and nothing is created. If not provided, the account's default payment method is used; if the account don't have one, the payment is created without one. |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Summary of the action performed (e.g., "Supplier invoice payment successfully created") |
| reference | String | Reference of the payment that was created (the auto-generated UUID on insert, or the provided reference otherwise) |
Deposits
POST deposits-create
It creates a client deposit in the specified project.
curl --location 'https://api.ezus.app/deposits-create' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data-raw '{
"project_reference": "project_reference",
"alternative_order": "0",
"type": "deposit",
"notes": "Up-front payment 2023-05-25",
"date": "2023-05-25",
"amount": 6855,
"payment_method": "card"
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
project_reference: "project_reference",
alternative_order: "0",
type: "deposit",
notes: "Up-front payment 2023-05-25",
date: "2023-05-25",
amount: 6855,
payment_method: "card",
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/deposits-create", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Deposit successfully created"
}
HTTP Endpoint
POST https://api.ezus.app/deposits-create
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| project_reference | String | Required The reference is mandatory and refers to the project to which the payment will be added. |
| alternative_order | String | Alternative number, if not entered, the payment will be added to the project's main alternative. |
| type | String | Type can be deposit, payment, final_payment, extra_paid. By default the deposits will be a deposit |
| notes | String | Note attributed to the payment, this note is limited to 100 characters, all additional characters will not be saved. |
| date | String | The date must be a string in "YYYY-MM-DD" format. If it is not filled in or is invalid, the payment will be assigned to the current date. |
| amount | Integer | Required The deposit amount in cents. |
| payment_method | String | Technical name of the payment method, you can find it in Settings - Custom fields |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of deposit action was created |
Tags
GET tags
Retrieves a list of your tags (product, supplier, client, or package) sorted by type. The list of tags returned is paginated (50 per 50): to call the 50 next items in the list, call the route with the next_token query parameter.
curl --location 'https://api.ezus.app/tags' \
--header 'X-API-KEY: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"X-API-KEY": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/tags", headers);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "<NEXT_TOKEN>",
"size": 338,
"data_size": 50,
"page": 1,
"tags": [
{
"reference": "partner",
"type": "client",
"name": "Partner"
},
{
"reference": "premium",
"type": "package",
"name": "Premium"
},
{
"reference": "mice",
"type": "product",
"name": "MICE"
},
{
"reference": "mice",
"type": "supplier",
"name": "MICE"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/tags
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| X-API-KEY | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| next_token | String | Specify this parameter if you want to retrieve the following elements of a given list query |
| type | String | Specifies the tag type to retrieve. Possible values: product, supplier, client, or package |
Response
An array of JSON that contains your tags information.
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all tags have not been returned. Use it in another call to access the following tags |
| size | Number | The total number of tags available with these filters |
| data_size | Number | Number of tags returned on the current page |
| page | Number | The page number |
| tags | Array | Array of JSON tags (Tags) |
Media
GET media
Returns the media of one object, or of your media library. Without object_type, it returns the media from your library, sorted by creation date from newest to oldest; each media then carries the object_type and object_reference it is attached to, and both are empty when the media is not linked to anything. The list is paginated (50 per 50): to call the 50 next items in the list, call the route with the next_token query parameter.
curl --location 'https://api.ezus.app/media?object_type=supplier&object_reference=supplier_reference' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(
baseUrl + "/media?object_type=supplier&object_reference=supplier_reference",
headers
);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "",
"size": 2,
"data_size": 2,
"page": 1,
"medias": [
{
"reference": "media-beach-view",
"media_name": "Beach view",
"path_full": "https://ezus-media.s3.amazonaws.com/media/9a1a8617/1700000000000.jpg",
"object_type": "supplier",
"object_reference": "supplier_reference"
},
{
"reference": "7f2c1b64-3d0e-4c8a-9b1f-2e5d6a7b8c9d",
"media_name": "Lobby",
"path_full": "https://ezus-media.s3.amazonaws.com/media/7f2c1b64/1700000001000.jpg",
"object_type": "supplier",
"object_reference": "supplier_reference"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/media
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| next_token | String | Specify this parameter if you want to retrieve the following elements of a given list query. If this parameter is filled, other parameters are ignored. |
| object_type | String | The type of the object whose media you want. It must be one of: supplier, product, package, subdestination, step. It is mandatory when object_reference is provided. If no object is provided, the media library is returned. |
| object_reference | String | The reference of the object whose media you want. It is mandatory when object_type is provided. An unknown reference answers an error naming the object type. |
| reference | Dynamic filter | Filter on the media reference. |
| media_name | Dynamic filter | Filter on the media name. |
All filters are cumulative (AND): a media must match every supplied filter to be returned.
Response
A JSON object containing the media information with properties like:
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all media have not been returned. Use it in another call to access the following media |
| size | Number | The total number of media available with these filters |
| data_size | Number | Number of media returned on the current page |
| page | Number | The page number |
| medias | Array | An array of JSON objects, each representing a media (Media) |
POST media-create
It creates a media (image) from a given image URL and adds it to your media library. The media can optionally be attached to a supplier, a product, a package, a step or a subdestination: it is then always added in the last position of the object's media list. The body is either one media or a list of up to 10 media: each media of a list is created or refused on its own, and the response carries one result per media, in the order of the list.
curl --location 'https://api.ezus.app/media-create' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data-raw '{
"reference": "media_reference",
"media_name": "Hotel pool",
"path_full": "https://example.com/images/hotel-pool.jpg",
"object_type": "supplier",
"object_reference": "supplier_reference"
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "media_reference",
media_name: "Hotel pool",
path_full: "https://example.com/images/hotel-pool.jpg",
object_type: "supplier",
object_reference: "supplier_reference",
};
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/media-create", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Media successfully created",
"reference": "media_reference"
}
Request with a list of media, on one or several objects:
curl --location 'https://api.ezus.app/media-create' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data-raw '[
{
"reference": "media_pool",
"media_name": "Hotel pool",
"path_full": "https://example.com/images/hotel-pool.jpg",
"object_type": "supplier",
"object_reference": "supplier_reference"
},
{
"media_name": "Lobby",
"path_full": "https://example.com/images/lobby.jpg",
"object_type": "supplier",
"object_reference": "supplier_reference"
},
{
"media_name": "Day 1",
"path_full": "https://example.com/images/day-1.webp",
"object_type": "step",
"object_reference": "project_step_reference"
}
]'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = [
{
reference: "media_pool",
media_name: "Hotel pool",
path_full: "https://example.com/images/hotel-pool.jpg",
object_type: "supplier",
object_reference: "supplier_reference",
},
{
media_name: "Lobby",
path_full: "https://example.com/images/lobby.jpg",
object_type: "supplier",
object_reference: "supplier_reference",
},
{
media_name: "Day 1",
path_full: "https://example.com/images/day-1.webp",
object_type: "step",
object_reference: "project_step_reference",
},
];
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/media-create", body, headers);
A list returns one result per media, in the order of the list:
{
"error": "false",
"message": "ok",
"action": "2 media successfully created ; 1 media failed",
"results": [
{
"error": "false",
"reference": "media_pool"
},
{
"error": "false",
"reference": "7cf94544-7e56-4e94-93cc-822d2cd9056d"
},
{
"error": "true",
"message": "The image format is not supported. Supported formats are: jpg, jpeg, png, gif, jfif"
}
]
}
HTTP Endpoint
POST https://api.ezus.app/media-create
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
One JSON object with the parameters below, or a list of 1 to 10 such objects. A list is refused as a whole when it is empty, holds more than 10 media, gives the same reference twice, or holds an element that is not a JSON object; the field named in the error then carries the index of the element, as in [1].path_full. Any other error only concerns its own media.
| Parameter | Type | Description |
|---|---|---|
| reference | String | Unique identifier of the media, it must be less than 36 characters long and unique among your non-deleted media. If not provided, a reference is generated and returned in the response. This endpoint only works in creation mode. This field is ignored when object_type is step. |
| media_name | String | Required The name of the media, limited to 300 characters. |
| path_full | String | Required The URL of the image to download, limited to 500 characters. Supported formats are jpg, jpeg, png, gif and jfif, with a maximum size of 20 MB. |
| object_type | String | The type of object to link the media to. It must be one of: supplier, product, package, subdestination, step. It is mandatory when object_reference is provided. If no object is provided, the media is only added to your media library. |
| object_reference | String | The reference of the object to link the media to. It is mandatory when object_type is provided. The media is added in last position of the object's media. |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | If the media has been created. With a list, how many media were created and how many failed |
| reference | String | The reference of the created media (provided or generated). Absent for a media attached to a step, and absent with a list |
| results | Array | Only with a list: one JSON object per media, in the order of the list. A created media carries error "false" and its reference (absent for a step); a refused media carries error "true" and the message saying why. The media of a list are added to their object in the order of the list |
Tasks
GET tasks
Returns the tasks of your account, sorted by due date in ascending order (oldest first). The list is paginated (50 per 50): to call the 50 next items in the list, call the route with the next_token query parameter.
curl --location 'https://api.ezus.app/tasks?is_done=false&assignee=tommy@e-corp.com&due_at_lte=2026-10-31' \
--header 'x-api-key: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"x-api-key": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(
baseUrl +
"/tasks?is_done=false&assignee=tommy@e-corp.com&due_at_lte=2026-10-31",
headers
);
This request returns a structured JSON object:
{
"error": "false",
"next_token": "",
"size": 2,
"data_size": 2,
"page": 1,
"tasks": [
{
"title": "Call the hotel back",
"description": "Confirm the rooming list before the deposit",
"due_at": "2026-10-07",
"is_done": false,
"assignee": {
"email": "tommy@e-corp.com",
"first_name": "Tommy",
"last_name": "Atkins",
"agency": "Paris Agency"
},
"created_by": {
"email": "travel-design@e-corp.com",
"first_name": "Jane",
"last_name": "Doe",
"agency": "Paris Agency"
},
"project": {
"reference": "project_reference",
"info_title": "Japan in autumn"
},
"client": {
"reference": "client_reference",
"company_name": "Moke International"
},
"created_at": "2026-09-30"
},
{
"title": "Trip end date",
"description": "",
"due_at": "2026-10-08",
"is_done": false,
"assignee": {
"email": "tommy@e-corp.com",
"first_name": "Tommy",
"last_name": "Atkins",
"agency": "Paris Agency"
},
"created_by": "None",
"project": {
"reference": "project_reference_2",
"info_title": "Costa Rica discovery"
},
"client": "None",
"created_at": "2026-10-01"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/tasks
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| x-api-key | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| next_token | String | Specify this parameter if you want to retrieve the following elements of a given list query. If this parameter is filled, other parameters are ignored. |
| title | Dynamic filter | Filter on the title of the task. |
| assignee | String | Provide either the email address of the user the task is assigned to or "None" for the unassigned tasks. Expected format: "john.doe@e-corp.com" or "None". |
| created_by | String | Provide either the email address of the user who created the task or "None" for the tasks created automatically. Expected format: "john.doe@e-corp.com" or "None". |
| is_done | Boolean | true returns the completed tasks, false the tasks still to do. Without it, both are returned. |
| project_reference | String | Reference of the project the task is linked to. |
| client_reference | String | Reference of the client the task is linked to. |
| due_at | Dynamic date filter | Filter on the due date of the task. Expected format: "YYYY-MM-DD". |
| created_at | Dynamic date filter | Filter on the creation date of the task. Expected format: "YYYY-MM-DD". |
All filters are cumulative (AND): a task must match every supplied filter to be returned.
Email addresses given to assignee and created_by must be URL-encoded: a + sent as is reads as a space, so jane+travel@e-corp.com is passed as jane%2Btravel%40e-corp.com.
Response
A JSON object containing the tasks information with properties like:
| Property | Type | Description |
|---|---|---|
| next_token | String | A token will be returned if all tasks have not been returned. Use it in another call to access the following tasks |
| size | Number | The total number of tasks available with these filters |
| data_size | Number | Number of tasks returned on the current page |
| page | Number | The page number |
| tasks | Array | An array of JSON objects, each representing a task (Task) |
Webhooks
GET webhooks
Retrieves a list of webhook endpoints, sorted by creation date from newest to oldest.
curl --location 'https://api.ezus.app/webhooks' \
--header 'X-API-KEY: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"X-API-KEY": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/webhooks", headers);
This request returns a structured JSON object:
{
"error": "false",
"webhooks": [
{
"reference": "webhook_reference",
"endpoint": "webhook_endpoint",
"events_types": "projects.created,clients.created",
"is_active": "true",
"last_called_at": "2023-01-01 01:01:01"
}
]
}
HTTP Endpoint
GET https://api.ezus.app/webhooks
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| X-API-KEY | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Response
An array of JSON that contains your webhooks information.
| Property | Type | Description |
|---|---|---|
| webhooks | Array | Array of JSON webhooks (Webhooks) |
GET webhooks-last
Returns the latest event occurrence of a specified event type.
curl --location 'https://api.ezus.app/webhooks-last?event_type=projects.created' \
--header 'X-API-KEY: <YOUR_API_KEY>' \
--header 'Authorization: Bearer <YOUR_TOKEN>'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const headers = {
"X-API-KEY": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.get(baseUrl + "/webhooks-last?event_type=projects.created", headers);
This request returns a structured JSON object:
{
"id": "event_id",
"object": "event",
"type": "projects.created",
"field": "",
"old_value": "",
"new_value": "",
"created": 1234567890,
"trigger_reference": "pro.ezus.io;projects-create",
"is_duplication": false,
"data": {...}
}
HTTP Endpoint
GET https://api.ezus.app/webhooks-last
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| X-API-KEY | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| event_type | String | Required The event type to retrieve |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message. If successful, it returns the latest event occurrence of a specified event type (Events).
POST webhooks-upsert
It updates a webhook record if the provided reference or endpoint does match one of the webhooks in your account, otherwise it creates a new webhook record with the provided reference (or with a random one if no reference is provided).
curl --location 'https://api.ezus.app/webhooks-upsert' \
--header 'X-API-KEY: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"reference": "webhook_reference",
"endpoint": "https://webhook.webhook/",
"is_active": "true",
"events_types": "projects.created,clients.created"
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "webhook_reference",
endpoint: "https://webhook.webhook/",
is_active: "true",
events_types: "projects.created,clients.created",
};
const headers = {
"X-API-KEY": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.post(baseUrl + "/webhooks-upsert", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Webhook successfully created",
"reference": "webhook_reference"
}
HTTP Endpoint
POST https://api.ezus.app/webhooks-upsert
Header Parameters
| Parameter | Type | Description |
|---|---|---|
| X-API-KEY | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body Parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | If provided, the unique reference associated to the webhook you want to update or create (in case the one you provided has never been used). If no reference is provided, a webhook will be created with a random one. |
| endpoint | String | If provided, the endpoint associated to the webhook you want to update or create (in case the one you provided has never been used). This parameter is required if you create a new webhook and has to be unique. You cannot update the endpoint of an existing webhook. |
| is_active | String | Status of the webhook true or false |
| events_types | JSON | The list of events to enable for this endpoint. At least 1 required, separated by commas if more than one. (Events) |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
| Property | Type | Description |
|---|---|---|
| action | String | Indicates type of webhook action was created |
| reference | String | The reference for the webhook, which you should store for future updates or retrievals |
DELETE webhooks-delete
It deletes a webhook record if the provided reference or endpoint does match one of the webhooks in your account.
curl --request "DELETE" \
--location 'https://api.ezus.app/webhooks-delete' \
--header 'X-API-KEY: <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <YOUR_TOKEN>' \
--data '{
"reference": "webhook_reference",
"endpoint": "https://webhook.webhook/"
}'
const axios = require("axios");
const baseUrl = "https://api.ezus.app";
const body = {
reference: "webhook_reference",
endpoint: "https://webhook.webhook/",
};
const headers = {
"X-API-KEY": "<YOUR_API_KEY>",
Authorization: "Bearer <YOUR_TOKEN>",
};
axios.delete(baseUrl + "/webhooks-delete", body, headers);
This request returns a structured JSON object:
{
"error": "false",
"message": "ok",
"action": "Webhook successfully deleted"
}
HTTP Endpoint
DELETE https://api.ezus.app/webhooks-delete
Header parameters
| Parameter | Type | Description |
|---|---|---|
| X-API-KEY | String | Required Your Ezus API key |
| Authorization | String | Required Your Bearer token |
Body parameters (application/json)
| Parameter | Type | Description |
|---|---|---|
| reference | String | If provided, the unique reference associated to the webhook you want to delete |
| endpoint | String | If provided, the endpoint associated to the webhook you want to delete |
Response
A JSON object indicating whether an error occurred during the process, along with the associated message.
Nested Resources
Account
"account": {
"name": "E-Corp Travels",
"currency": "EUR"
}
| Property | Type | Description |
|---|---|---|
| name | String | Company name of the account |
| currency | String | Default currency of the account |
Account Currencies
The currencies of the account and their exchange rates.
"currencies": {
"reference": "EUR",
"catalog": "EUR",
"projects": "USD",
"library": [
{ "code": "EUR", "name": "Euro", "rate": 1 },
{ "code": "USD", "name": "US dollar", "rate": 1.08 },
{ "code": "CHF", "name": "Swiss franc", "rate": 2.2223 }
]
}
| Property | Type | Description |
|---|---|---|
| reference | String | Code of the reference currency, the one every rate is quoted against. The same as currency in Account |
| catalog | String | Code of the default currency of new catalog products |
| projects | String | Code of the default sales currency of new projects |
| library | Array | Currencies of the account, the reference first, then in the order they were added |
Each currency:
| Property | Type | Description |
|---|---|---|
| code | String | Code of the currency, as the currency of the write routes takes it. ISO 4217, except for a few Ezus codes such as CFA or BTC |
| name | String | English name of the currency |
| rate | Number | Amount of this currency worth 1 unit of the reference currency. 1 for the reference itself |
Account Defaults
The settings of the account a new record is created with and its prices, margins and VAT are computed with. A setting the account never changed carries the value Ezus applies.
"default": {
"lang": "french",
"client_type": "enterprise",
"activity_start": "09:00:00",
"activity_end": "18:00:00",
"activity_hours": "start_and_end",
"step_title_accommodation_transportation": "supplier_name",
"step_title_activity": "product_name",
"step_description": "short",
"price_display": "excluded_taxes",
"margin_based_on": "sales_price",
"margin_rate": 20,
"margin_calculation": "per_product",
"price_update_behavior": "adjust_margin_rate",
"is_margin_rate_per_client_enabled": true,
"vat_regime": "classic",
"vat_rate": 20,
"vat_rate_margin": 20,
"vat_classic_calculation_mode": "line",
"vat_not_applicable_is_recoverable": false,
"commission_based_on": "sales_price",
"project_global_supplements": {
"fees": 1452,
"fees_type": "flat",
"discount": 10,
"discount_type": "percentage"
},
"purchase_invoices_based_on": "total_invoiced_purchase_price",
"purchase_invoices_due_date": "day_plus_30",
"create_payment_after_invoice": true,
"paid_invoice_mention": null
}
General:
| Property | Type | Description |
|---|---|---|
| lang | String | Default language, as the name of Account Languages |
| client_type | String | Type of a new client. Possible values: enterprise, individual, as the type of a client |
Steps:
| Property | Type | Description |
|---|---|---|
| activity_start | String | Start time of a new activity step, "HH:MM:SS". null when activity_hours is none |
| activity_end | String | End time of a new activity step, "HH:MM:SS". null unless activity_hours is start_and_end |
| activity_hours | String | Hours a new activity step gets. Possible values: none (no time), start_only (activity_start, no end), start_and_end |
| step_title_accommodation_transportation | String | Title of a new accommodation or transport step. Possible values: supplier_name, product_name |
| step_title_activity | String | Title of a new activity or extra step. Possible values: supplier_name, product_name |
| step_description | String | Description a new step takes from its product. Possible values: short, long. null when none is set |
Budget:
| Property | Type | Description |
|---|---|---|
| price_display | String | Prices shown in the budget. Possible values: excluded_taxes, included_taxes |
| margin_based_on | String | Price the margin rate is shown against. Possible values: sales_price, purchase_price |
| margin_rate | Number | Default margin rate, in percent of the price margin_based_on names, as the settings show it. sales_price: a sales price is the purchase price divided by 1 - margin_rate / 100; purchase_price: it is the purchase price times 1 + margin_rate / 100 |
| margin_calculation | String | How the margin of a project is computed. Possible values: per_product, global |
| price_update_behavior | String | What changes when a price of a product is edited. Possible values: adjust_margin_rate (the margin rate follows), keep_margin_rate (the other price follows). null when none is set |
| is_margin_rate_per_client_enabled | Boolean | Whether a client can carry a margin rate of its own |
VAT:
| Property | Type | Description |
|---|---|---|
| vat_regime | String | VAT regime, as vat_regime on the product and item routes. Possible values: margin (VAT on the margin), classic (common law VAT), none (non applicable VAT). null when the account has no regime set |
| vat_rate | Number | Default VAT rate, in percent |
| vat_rate_margin | Number | VAT rate applied to the margin and to the fees, in percent |
| vat_classic_calculation_mode | String | Rate the classic regime applies. Possible values: line (the rate of each line), vat_rate_margin, vat_rate |
| vat_not_applicable_is_recoverable | Boolean | Whether the purchase VAT is recovered under the none regime |
Commission and fees:
| Property | Type | Description |
|---|---|---|
| commission_based_on | String | Price a commission in percent applies to. Possible values: sales_price, purchase_price |
| project_global_supplements | JSON | Fee and discount of a new project |
project_global_supplements:
| Property | Type | Description |
|---|---|---|
| fees | Number | Amount of the fee: a percentage or an amount in the reference currency, per fees_type |
| fees_type | String | Possible values: percentage, flat |
| discount | Number | Amount of the discount: a percentage or an amount in the reference currency, per discount_type |
| discount_type | String | Possible values: percentage, flat |
Purchases:
| Property | Type | Description |
|---|---|---|
| purchase_invoices_based_on | String | Purchase total the finances of a new project are computed from: the budget or the supplier invoices. Possible values: total_forecast_purchase_price, total_invoiced_purchase_price. null when none is set |
| purchase_invoices_due_date | String | Due date of a new supplier invoice. Possible values: none, day (its invoice date), day_plus_1, day_plus_2, day_plus_3, day_plus_4, day_plus_5, day_plus_7, day_plus_14, day_plus_30, day_plus_60, day_plus_90 |
Sales:
| Property | Type | Description |
|---|---|---|
| create_payment_after_invoice | Boolean | Whether a client payment is created with a new invoice |
| paid_invoice_mention | String | Mention stamped on a paid invoice. Possible values: paid, settled. null when none |
Account Deleted Users
The deleted users of the account, the last deleted first. A record created by a user who was deleted since still carries the email of that user: this list names it. An email appears once, and never when a live user of Account Users holds it again.
"users_deleted": [
{
"reference": "former@e-corp.com",
"first_name": "Paul",
"last_name": "Martin",
"email": "former@e-corp.com",
"role": "user",
"is_technical_user": false
}
]
| Property | Type | Description |
|---|---|---|
| reference | String | Identifier of the user, its email, as the records it owned carry it |
| first_name | String | First name of the user, "" when none is set |
| last_name | String | Last name of the user, "" when none is set |
| String | Email of the user | |
| role | String | Role the user had, as role in Authenticated User |
| is_technical_user | Boolean | Whether the user was a technical user, as is_technical_user in Account Users |
Account Languages
The languages the account writes its descriptions in.
"languages": {
"default": "french",
"library": [
{ "code": "fr", "name": "french", "label": "French" },
{ "code": "us", "name": "american", "label": "English (US)" }
]
}
| Property | Type | Description |
|---|---|---|
| default | String | name of the default language of the account, the one a new project is written in |
| library | Array | Languages activated in the language library of the account |
Each language:
| Property | Type | Description |
|---|---|---|
| code | String | Short code of the language. Possible values: fr, en, us, es, it, pt, de, nl, no, cu (the custom language) |
| name | String | Name of the language, the lang of a Langs entry on the write routes |
| label | String | English label of the language |
Account Users
The users of the account, in the order they were created. A deactivated user is listed with is_active false; a deleted one is listed in Account Deleted Users instead.
"users": [
{
"reference": "tommy@e-corp.com",
"first_name": "Tommy",
"last_name": "Atkins",
"email": "tommy@e-corp.com",
"role": "admin",
"is_active": true,
"is_technical_user": false
}
]
| Property | Type | Description |
|---|---|---|
| reference | String | Identifier of the user on the write routes: the sales_manager_email of POST /projects-upsert, the user of POST /clients-upsert |
| first_name | String | First name of the user, "" when none is set |
| last_name | String | Last name of the user, "" when none is set |
| String | Email of the user | |
| role | String | Role of the user, as role in Authenticated User |
| is_active | Boolean | Whether the user is active, false once deactivated |
| is_technical_user | Boolean | Whether the user is a technical user, not counted among the users of the account: flagged as such, or with an Ezus address (@ezus.io) |
Authenticated User
"user": {
"email": "tommy@e-corp.com",
"first_name": "Tommy",
"last_name": "Atkins",
"role": "admin"
}
| Property | Type | Description |
|---|---|---|
| String | Email of the user | |
| first_name | String | First name of the user |
| last_name | String | Last name of the user |
| role | String | Role of the user. Ezus ships with super_admin, admin, user and collaborator; a role your account created itself keeps its own name |
Address
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
}
| Property | Type | Description |
|---|---|---|
| label | String | Street part of the address, as sent (the city, zip and country are returned in their own fields) |
| city | String | Name of the city |
| country | String | Name of the country |
| zip | String | Post code |
| geo | JSON | Represents the geographical coordinates of the address or null if not geolocated. If provided, it consists of x (latitude, between -90 and 90) and y (longitude, between -180 and 180), both returning a Number with 6 decimals. On suppliers-upsert and clients-upsert, geo is optional: omit it or send null to store the address without coordinates. |
Alternatives
"alternatives": [
{
"reference": "550e8400-e29b-41d4-a716-446655440000",
"alternative_title": "Main Alternative",
"lang": "fr-FR",
"is_main": true,
"is_sig": false,
"trip_date_in": "2024-03-01",
"trip_date_out": "2024-03-09",
"trip_duration": 9,
"trip_people": "15",
"trip_destination_reference": "destination_reference",
"trip_destination": "France",
"trip_subdestination_reference ": "subdestination_reference",
"trip_subdestination": "Paris",
"trip_budget": 90000,
"budget_actual": 88750,
"budget_actual_excl_taxes ": 77950,
"budget_margin_gross": 2500,
"budget_margin_net": 1000,
"budget_purchases": 74500,
"financial_invoiced": 48000,
"financial_collected": 48000,
"financial_purchases": 72820,
"financial_spendings": 12820,
"destinations": {
"size": 3,
"data": [
{
"reference": "destination_reference",
"name": "France",
"subdestination_reference": "subdestination_reference",
"subdestination_name": "Paris"
},
{
"reference": "destination_reference",
"name": "France",
"subdestination_reference": "subdestination_reference1-2",
"subdestination_name": "Lyon"
},
{
"reference": "destination_reference2",
"name": "Italy",
"subdestination_reference": "subdestination_reference2-1",
"subdestination_name": "Milan"
}
]
},
"client": {
"reference": "client_reference",
"type": "enterprise",
"company_name": "MOKE INTERNATIONAL LIMITED",
"first_name": "Jane",
"last_name": "Doe",
"email": "contact@moke-international.com"
},
"client_space": {
"is_live": true,
"url": "https://custom-domain.com/your-space-slug",
"description": "Description of the client space",
"image_url": "https://image.jpg"
},
"brand": {
"title": "INTERNATIONAL LIMITED",
"company_name": "MOKE INTERNATIONAL LIMITED",
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010"
},
"email": "travel-design@e-corp.com",
"phone": "0101010101",
"website": "www.moke_ltd.com",
"vat_number": "GB 240-635-038",
"company_number": "09728676"
}
}
]
| Property | Type | Description |
|---|---|---|
| reference | String | Unique reference of this alternative: (distinct from the root project reference at the top level of the GET project response). |
| alternative_title | String | Title of the alternative |
| lang | String | Alternative locale code (e.g. fr-FR, en-GB) |
| is_main | Boolean | If the alternative is the main alternative |
| is_sig | Boolean | If the alternative is in group mode (GIR): its travellers are split into groups (Groups) |
| trip_date_in | Date | Date of the beginning of this alternative, in a "YYYY-MM-DD" format string. If it's empty, the project has no dates |
| trip_date_out | Date | Date of the end of this alternative, in a "YYYY-MM-DD" format string. If it's empty, the project has no dates |
| trip_duration | Number | Number of days this alternative lasts |
| trip_people | String | Number of people |
| trip_destination_reference | String | Destination reference of the alternative. Note: For multi-destination alternatives, only the primary destination is returned. |
| trip_destination | String | Destination of the alternative. Note: For multi-destination alternatives, only the primary destination is returned. |
| trip_subdestination_reference | String | Subdestination reference of the alternative. Note: For multi-destination alternatives, only the primary subdestination is returned. |
| trip_subdestination | String | Subdestination of the alternative. Note: For multi-destination alternatives, only the primary subdestination is returned. |
| trip_budget | Number | Forecasted budget for the alternative (the one that is entered manually not the actual one) |
| budget_actual | Number | Actual budget for the alternative, inclusive of taxes |
| budget_actual_excl_taxes | Number | Actual budget for the alternative, excluding taxes |
| budget_margin_gross | Number | Gross margin for the alternative |
| budget_margin_net | Number | Net margin for the alternative |
| budget_purchases | Number | Planned supplier purchases amount for the alternative (in project currency). This is a forecasted value, not actual spending |
| financial_invoiced | Number | Total amount invoiced to clients for the alternative (in project currency). Draft invoices are not included in this calculation |
| financial_collected | Number | Total amount collected from clients for the alternative (in project currency). Represents actual payments received |
| financial_purchases | Number | Actual supplier purchase costs for the alternative (in project currency). Corresponds to recorded supplier invoices |
| financial_spendings | Number | Actual spendings recorded for the alternative (in project currency). Includes all types of supplier payments (purchases, fees, etc.) |
| destinations | JSON | JSON including: size, Array of all destination (reference and name) and subdestination (subdestination_reference and subdestination_name) values |
| client | JSON | JSON including: reference, type (enterprise or individual), company_name, first_name, last_name and email |
| client_space | JSON | JSON including: is_live (Boolean), url (empty string when not live; uses slug when available, otherwise ?id=; custom domain when configured, fallback to docs.ezus.io), description, image_url |
| brand | JSON | JSON object representing the brand (Brand) associated with the alternative |
Brand
If no brand is associated with an alternative, the default values are taken from the user’s company settings.
"brand": {
"title": "INTERNATIONAL LIMITED",
"company_name": "MOKE INTERNATIONAL LIMITED",
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010"
},
"email": "travel-design@e-corp.com",
"phone": "0101010101",
"website": "www.moke_ltd.com",
"vat_number": "GB 240-635-038",
"company_number": "09728676"
}
| Property | Type | Description |
|---|---|---|
| title | String | Title of the brand |
| company_name | String | Name of the brand company |
| address | JSON | JSON object representing the address (Address) of the brand |
| String | Email of the brand | |
| phone | String | Phone of the brand |
| website | String | Website link of the brand |
| vat_number | String | VAT number of the brand |
| company_number | String | Company registration number of the brand |
Contacts
Only the last 10 contacts are returned in this object. Note that for upsert endpoints, only one contact is required (equivalent to a single JSON element in the contacts.data Array below).
"contacts": {
"data": [
{
"reference": "contact_reference",
"email": "contact@moke.com",
"first_name": "Jane",
"last_name": "Doe",
"title": "CEO",
"gender": "Ms",
"phone": "0101010101",
"phone2": "0606060606",
"birth_date": "1986-09-17",
"is_main": true
},
{
"reference": "contact_reference",
"email": "bob@proton.me",
"first_name": "Bob",
"last_name": "Morane",
"title": "Project Manager",
"gender": "Mr",
"phone": "0202020202",
"phone2": "0707070707",
"birth_date": "1985-10-18",
"is_main": false
}
],
"size": 2
}
| Property | Type | Description |
|---|---|---|
| reference | String | Reference of the contact |
| String | Email of the contact | |
| first_name | String | First name of the contact as a string |
| last_name | String | Last name of the contact as a string |
| title | String | Title of the contact as a string |
| gender | String | Mr, Ms or Undefined |
| phone | String | Phone number of the contact as a string |
| phone2 | String | Second phone number of the contact as a string |
| birth_date | String | Contact's date of birth in a "YYYY-MM-DD" format string (supplier contacts have no date of birth) |
| is_main | Boolean | True if this contact is the primary contact for the parent resource |
Custom Field Definitions
The custom fields an account defined, one list per object type. A field is written and read by its reference, as the name of a Custom Fields entry. Each list is grouped by family, in the order the account sorts them: the fields without family first, then each family, each field in its order within its family.
"custom_fields": {
"project": [
{
"name": "Trip theme",
"reference": "trip-theme",
"type": "select",
"options": ["Incentive", "Seminar", "Leisure"],
"default": "Seminar",
"description": "Theme announced to the client",
"family": "General"
}
],
"budget": [],
"products": [],
"packages": [],
"suppliers": [],
"clients": [],
"travellers": [],
"invoices": [],
"payment_methods": [],
"options": [],
"texts": []
}
| Property | Type | Description |
|---|---|---|
| project | Array | Fields of the project brief |
| budget | Array | Fields of the project budget |
| products | Array | Fields of the catalog products |
| packages | Array | Fields of the packages |
| suppliers | Array | Fields of the suppliers, whatever their family |
| clients | Array | Fields of the clients |
| travellers | Array | Fields of the travellers. POST /project-travellers-create only writes the text and number ones |
| invoices | Array | Fields of the invoices |
| payment_methods | Array | Payment methods of the account, one entry each. The reference is the payment_method of POST /deposits-create. Empty while the account uses the Ezus default ones |
| options | Array | Option labels an item can carry, one entry each. Empty while the account uses the Ezus default ones |
| texts | Array | Wordings the account renamed: name is its wording, default the Ezus one |
Each field:
| Property | Type | Description |
|---|---|---|
| name | String | Display name of the field |
| reference | String | Technical name of the field, the name to send in custom_fields on the write routes |
| type | String | Type of the field. Possible values: text, textarea, number, date, time, checkbox, select, multi_select, url, file |
| options | Array | Values a select or multi_select field accepts, to write exactly as listed. null for the other types |
| default | Mixed | Value of a new record: a string for text, textarea, select, url; a number for number; true or false for checkbox; "YYYY-MM-DD" for date; "HH:MM" for time; an array of options for multi_select. null when none is set, and always for file |
| description | String | Description of the field. null when none is set |
| family | String | Name of the family of the field, General when it has none |
Custom Fields
"custom_fields": [
{
"name": "Text",
"value": "Value"
},
{
"name": "Number",
"value": "42"
},
{
"name": "Text area",
"value": "Value of the text Area"
},
{
"name": "Date",
"value": "2012-12-21"
},
{
"name": "Time",
"value": "2006-10-07T12:06:56.568+01:00"
},
{
"name": "URL link",
"value": "https://urllink.com"
},
{
"name": "File",
"value": "https://urllink.com/files/document.pdf"
},
{
"name": "Checkbox",
"value": "true"
},
{
"name": "Dropdown",
"value": "ExactOption"
},
{
"name": "MultipleDropdown",
"value": "ExactOption1/-/ExactOption2"
}
]
The technical name of a custom field can be found in the custom field edit modal
| Options | Type | Description |
|---|---|---|
| Text | String | Simple string like Text Area |
| Dropdown | String | The option must be written exactly as in the parameters, respecting the case |
| Multiple Dropdown | String | The option must be written exactly as in the parameters, respecting the case, for Multiple Answer you should enter Option1/-/Option2/-/Option3 in a string, "/-/" should separate each options |
| Date | String | The date must be in a "YYYY-MM-DD" format string |
| Time | String | The time must be in a "YYYY-MM-DDTHH:MM:SS+01:00" format string |
| Checkbox | String | The checkbox must be a string: "true" (checked) OR "false" (unchecked) |
| Number | String | Number type should be a Number without other character |
| File | String | File must be a valid URL, and supported file extensions include: .pdf, .jpg, .jpeg, .png, .bmp, .gif, .docx, .doc, .msg, .odt, .rtf, .txt, .ppt, .pptx, .pptm, .csv, .xlsx |
Category
"category": {
"reference": "category_reference",
"name": "Accommodation / Lodging",
"subcategory_reference": "subcategory_reference",
"subcategory_name": "Hotel Room"
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the category |
| name | String | Name of the category |
| subcategory_reference | String | The reference of the sub-category |
| subcategory_name | String | Name of the sub-category |
Categories
"categories": [
{
"reference": "category_reference",
"name": "Experiences",
"subcategories": [
{
"reference": "subcategory_reference",
"name": "Relaxation"
}
]
}
]
Each object represents a category with its associated sub-categories
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the category |
| name | String | Name of the category |
| subcategories | Array | An array of JSON objects, each representing a sub-category along with its name and reference |
Config
The configuration of the account, returned by GET /me?include=config.
"config": {
"project_statuses": {
"ongoing": [
{
"name": "Quote sent",
"reference": "quote_sent",
"color": "#00b3ff"
}
],
"archived": [
{
"name": "Paid",
"reference": "paid",
"color": "#7ed321"
}
],
"template": [
{
"name": "Seminar",
"reference": "seminar",
"color": "#e25050"
}
]
},
"notes_default": {
"project": "Budget and dates to confirm with the client",
"products": "",
"packages": "",
"suppliers": "Ask for the group rates",
"clients": ""
},
"custom_fields": {
"project": [
{
"name": "Trip theme",
"reference": "trip-theme",
"type": "select",
"options": ["Incentive", "Seminar", "Leisure"],
"default": "Seminar",
"description": "Theme announced to the client",
"family": "General"
}
],
"budget": [],
"products": [],
"packages": [],
"suppliers": [],
"clients": [],
"travellers": [],
"invoices": [],
"payment_methods": [],
"options": [],
"texts": []
},
"seasons_groups": [
{
"name": "Summer",
"reference": "summer",
"seasons": [
{
"name": "High season",
"reference": "high_season",
"limit_start": "2026-07-01",
"limit_end": "2026-08-31",
"is_yearly": true
}
]
}
],
"step_categories": {
"accommodation": [
{
"name": "Hotel",
"reference": "hotel",
"is_favorite": true,
"custom_fields": [
{
"name": "Check-in time",
"reference": "check-in-time",
"type": "time",
"options": null,
"default": "15:00",
"description": null
}
]
}
],
"transport": [],
"activity": [],
"extra": []
},
"languages": {
"default": "french",
"library": [
{ "code": "fr", "name": "french", "label": "French" },
{ "code": "us", "name": "american", "label": "English (US)" }
]
},
"currencies": {
"reference": "EUR",
"catalog": "EUR",
"projects": "USD",
"library": [
{ "code": "EUR", "name": "Euro", "rate": 1 },
{ "code": "USD", "name": "US dollar", "rate": 1.08 },
{ "code": "CHF", "name": "Swiss franc", "rate": 2.2223 }
]
},
"invoice_numbering": [
{
"counter_name": "Invoices",
"format": "$$yyyy$$$$mm$$$$n$$",
"counter_size": 4,
"next_number": 208,
"reset": "never"
}
],
"reference_numbering": {
"enabled": true,
"projects": [
{
"counter_name": "MICE",
"format": "$$yyyy$$$$mm$$$$n$$-MICE$$ppp$$",
"counter_size": 5,
"next_number": 12,
"reset": "yearly"
}
],
"clients": [],
"suppliers": []
},
"legal_entity": {
"company_name": "E-Corp Travels",
"contact": {
"website": "https://e-corp.com",
"phone": "0601020304",
"email": "contact@e-corp.com"
},
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"zip": "75010",
"country": {
"label": "France",
"code": "FR",
"stripe_sepa_enabled": true,
"electronic_invoicing_enabled": true
}
},
"billing": {
"vat_number": "FR00123456789",
"company_number": "12345678900011",
"invoice_bank": "E-Bank",
"invoice_location": "Paris",
"invoice_iban": "FR76 3000 6000 0112 3456 7890 189",
"invoice_bic": "AGRIFRPP"
}
},
"default": {
"lang": "french",
"client_type": "enterprise",
"activity_start": "09:00:00",
"activity_end": "18:00:00",
"activity_hours": "start_and_end",
"step_title_accommodation_transportation": "supplier_name",
"step_title_activity": "product_name",
"step_description": "short",
"price_display": "excluded_taxes",
"margin_based_on": "sales_price",
"margin_rate": 20,
"margin_calculation": "per_product",
"price_update_behavior": "adjust_margin_rate",
"is_margin_rate_per_client_enabled": true,
"vat_regime": "classic",
"vat_rate": 20,
"vat_rate_margin": 20,
"vat_classic_calculation_mode": "line",
"vat_not_applicable_is_recoverable": false,
"commission_based_on": "sales_price",
"project_global_supplements": {
"fees": 1452,
"fees_type": "flat",
"discount": 10,
"discount_type": "percentage"
},
"purchase_invoices_based_on": "total_invoiced_purchase_price",
"purchase_invoices_due_date": "day_plus_30",
"create_payment_after_invoice": true,
"paid_invoice_mention": null
},
"users": [
{
"reference": "tommy@e-corp.com",
"first_name": "Tommy",
"last_name": "Atkins",
"email": "tommy@e-corp.com",
"role": "admin",
"is_active": true,
"is_technical_user": false
}
],
"users_deleted": [
{
"reference": "former@e-corp.com",
"first_name": "Paul",
"last_name": "Martin",
"email": "former@e-corp.com",
"role": "user",
"is_technical_user": false
}
]
}
| Property | Type | Description |
|---|---|---|
| project_statuses | JSON | Project statuses of the account, per group (Project Statuses) |
| notes_default | JSON | Notes a new project, product, package, supplier or client starts with (Default Notes) |
| custom_fields | JSON | Custom fields of the account, per object type (Custom Field Definitions) |
| seasons_groups | Array | Preset seasons of the account, per group (Seasons Groups) |
| step_categories | JSON | Step categories of the account, per step type (Step Categories) |
| languages | JSON | Default and active languages of the account (Account Languages) |
| currencies | JSON | Currency settings and exchange rates of the account (Account Currencies) |
| invoice_numbering | Array | Counters numbering the invoices of the account (Invoice Numbering) |
| reference_numbering | JSON | Counters of the automatic references of projects, clients and suppliers (Reference Numbering) |
| legal_entity | JSON | Company, contact, address and billing details of the account (Legal Entity) |
| default | JSON | Business defaults of the account, the settings a new record and its prices are computed with (Account Defaults) |
| users | Array | Users of the account (Account Users) |
| users_deleted | Array | Deleted users of the account, who may still own records (Account Deleted Users) |
Default Notes
The notes a new record starts with, one per object, as set in the settings of the account. Plain text, line breaks as \n.
"notes_default": {
"project": "Budget and dates to confirm with the client",
"products": "",
"packages": "",
"suppliers": "Ask for the group rates",
"clients": ""
}
| Property | Type | Description |
|---|---|---|
| project | String | Default notes of a new project, "" when none is set |
| products | String | Default notes of a new catalog product, "" when none is set |
| packages | String | Default notes of a new package, "" when none is set |
| suppliers | String | Default notes of a new supplier, "" when none is set |
| clients | String | Default notes of a new client, "" when none is set |
Destination
"destination": {
"reference": "destination_reference",
"name": "France",
"subdestination_reference": "subdestination_reference",
"subdestination_name": "Paris"
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the destination |
| name | String | Name of the destination |
| subdestination_reference | String | The reference of the sub-destination |
| subdestination_name | String | Name of the sub-destination |
Destinations
"destinations": [
{
"reference": "destination_reference",
"name": "France",
"subdestinations": [
{
"reference": "subdestination_reference",
"name": "Paris"
}
],
"langs": [
{
"lang": "french",
"name": "Un pays intéressant"
}
]
}
]
Each object represents a destination with its associated sub-destinations
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the destination |
| name | String | Name of the destination |
| subdestinations | Array | An array of JSON objects, each representing a sub-destination along with its name and reference |
| langs | Array | Array of JSON langs (Langs) - only name supported in this case |
Group Lines
"items": [
{
"reference": "item_reference",
"project_step_reference": "project_step_reference",
"name": "item_title",
"pax": 3,
"quantity": 9
}
]
The lines attributed to a group, in the order of the program. A line whose formula uses the variable T has a quantity per group: T is the number of pax of the group on the line, where P is the number of people of the project. quantity is that formula evaluated for the group, rounded to two decimals.
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the item (Items) |
| project_step_reference | String | The reference of the step of the item (Steps) |
| name | String | Name of the item |
| pax | Number | Number of pax of the group on this line. The whole group unless fewer pax were attributed |
| quantity | Number | Quantity of the line for the group, its formula evaluated with T equal to pax. null when the formula does not use T or divides by zero |
Groups
"groups": [
{
"reference": "project_group_reference",
"name": "Group A",
"pax": 1,
"primary_traveller_reference": "traveller_reference",
"travellers": [
{
"reference": "traveller_reference",
"first_name": "Emily",
"last_name": "Johnson",
"email": "emily.johnson@example.com"
}
],
"items": [
{
"reference": "item_reference",
"project_step_reference": "project_step_reference",
"name": "item_title",
"pax": 1,
"quantity": 3
}
],
"invoices": [
{
"reference": "invoice_reference"
}
]
}
]
The groups of an alternative in group mode (GIR), in the order of the project. An alternative outside group mode has no group.
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the group |
| name | String | Name of the group |
| pax | Number | Number of travellers in the group |
| primary_traveller_reference | String | The reference of the primary traveller of the group. null when the group has none |
| travellers | Array | Travellers of the group, each with reference, first_name, last_name and email |
| items | Array | Lines attributed to the group (Group Lines) |
| invoices | Array | Invoices of the group, each with its reference |
Invoice Numbering
The counters numbering the invoices of the account when they are finalized, each shaped as a Numbering Counter, the default one first. An empty list when the account has none.
"invoice_numbering": [
{
"counter_name": "Invoices",
"format": "$$yyyy$$$$mm$$$$n$$",
"counter_size": 4,
"next_number": 208,
"reset": "never"
}
]
Invoices Amounts
"forecast": {
"is_automatic": true,
"purchase": 0.0,
"commission": 0.0,
"vat_deducted": 0.0,
"amount_ht": 1000.0
}
"actual": {
"is_automatic": true,
"purchase": null,
"commission": null,
"vat_deducted": null,
"amount_ht": null
}
These objects provides insights into the invoice amounts, differentiating between actual figures and forecasts. Actual figures are available when the associated project is closed and the invoice is marked as completed or paid. Otherwise, null values are displayed.
| Property | Type | Description |
|---|---|---|
| is_automatic | Boolean | Automatically use the figures of the project to which this invoice/credit_note is linked |
| purchase | Number | Forecasted / Actual purchase |
| commission | Number | Forecasted / Actual commission |
| vat_deducted | Number | Forecasted / Actual deductible VAT |
| amount_ht | Number | Forecasted / Actual amount excluding taxes |
Invoices Lines
"lines": [
{
"title": "Private Suite at Hôtel Ritz Paris",
"quantity": 1,
"price": 1200,
"price_excl_taxes": 1000,
"description": "Luxury private suite accommodation at Hôtel Ritz Paris including premium amenities and concierge services.",
"tax_rate": 20,
"tax_regime": {
"name": "classic",
"category": "S",
"comment": ""
}
}
]
These objects represent the individual invoice lines associated with the invoice or credit note.
| Property | Type | Description |
|---|---|---|
| title | String | Title or short label of the invoiced service or product. When present, the fee line is returned with the title "Main fee" and the discount line with the title "Main discount". |
| quantity | Number | Quantity billed for this invoice line |
| price | Number | Total amount including taxes |
| price_excl_taxes | Number | Total amount excluding taxes |
| description | String | Detailed description of the invoiced service or product |
| tax_rate | Number | Tax rate applied to the line item, expressed as a percentage. |
| tax_regime.name | String | Tax profile applied to the invoice line. Possible values: none, margin, classic |
| tax_regime.category | String | Tax category code associated with the invoice line |
| tax_regime.comment | String | Additional tax-related information or comment |
Items
"items": [
{
"reference": "item_reference",
"name": "item_title",
"product_reference": "product_reference",
"supplier_reference": "supplier_reference",
"quantity": 2,
"purchase_price": 150,
"purchase_price_excl_taxes": 125,
"sales_price": 200,
"sales_price_excl_taxes": 166.67,
"is_optional": false,
"notes": "Notes about the item",
"booked": false
}
]
The items array represents a collection of items associated with a step.
The fields purchase_price, purchase_price_excl_taxes, sales_price, and sales_price_excl_taxes represent the price per unit of the item. To calculate the total cost or total sales value for an item, multiply the unit price by the quantity.
All prices returned by this endpoint are expressed in the project’s currency. If the items are in different currencies, conversion must be performed using the exchange rates available in the project’s currency library.
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the item |
| name | String | Name of the item |
| product_reference | String | The product reference associated with the item |
| supplier_reference | String | The supplier reference associated with the item |
| quantity | Number | Quantity of the item |
| purchase_price | Number | The unit purchase price of the item (including taxes) |
| purchase_price_excl_taxes | Number | The unit purchase price of the item (excluding taxes) |
| sales_price | Number | The unit sales price of the item (including taxes) |
| sales_price_excl_taxes | Number | The unit sales price of the item (excluding taxes) |
| is_optional | Boolean | Indicates whether the item is optional. If true, the item does not contribute to the final purchase or sales price. |
| notes | String | Notes about the item |
| booked | Boolean | Indicates whether the item has been booked / reserved. |
Langs
"langs": [
{
"lang": "american",
"name": "My American product version",
"short_description": "Short American Description",
"long_description": "Long American Description"
}
]
| Property | Type | Description |
|---|---|---|
| lang | String | Language name in lower case. Possible lang property values are: french, english, american, spanish, italian, portuguese, german, dutch, norwegian |
| name | String | Title of the object in this language |
| short_description | String | Short description of the object in this language |
| long_description | String | Long description of the object in this language |
Legal Entity
The company the account invoices as. A value the account never filled is null.
"legal_entity": {
"company_name": "E-Corp Travels",
"contact": {
"website": "https://e-corp.com",
"phone": "0601020304",
"email": "contact@e-corp.com"
},
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"zip": "75010",
"country": {
"label": "France",
"code": "FR",
"stripe_sepa_enabled": true,
"electronic_invoicing_enabled": true
}
},
"billing": {
"vat_number": "FR00123456789",
"company_number": "12345678900011",
"invoice_bank": "E-Bank",
"invoice_location": "Paris",
"invoice_iban": "FR76 3000 6000 0112 3456 7890 189",
"invoice_bic": "AGRIFRPP"
}
}
| Property | Type | Description |
|---|---|---|
| company_name | String | Company name |
| contact | JSON | Website, phone and generic email |
| address | JSON | Address of the company |
| billing | JSON | Details printed on its invoices |
contact:
| Property | Type | Description |
|---|---|---|
| website | String | Website of the company |
| phone | String | Phone of the company |
| String | Generic email of the company |
address:
| Property | Type | Description |
|---|---|---|
| label | String | Street address |
| city | String | City |
| zip | String | Postal code |
| country | JSON | Country of the company. null when none is set |
address.country:
| Property | Type | Description |
|---|---|---|
| label | String | English name of the country |
| code | String | ISO 3166-1 alpha-2 code of the country |
| stripe_sepa_enabled | Boolean | Whether Stripe offers SEPA direct debit in this country |
| electronic_invoicing_enabled | Boolean | Whether Ezus supports electronic invoicing in this country |
billing:
| Property | Type | Description |
|---|---|---|
| vat_number | String | VAT number of the company |
| company_number | String | Registration number of the company |
| invoice_bank | String | Bank printed on the invoices |
| invoice_location | String | Place of issue printed on the invoices |
| invoice_iban | String | IBAN printed on the invoices |
| invoice_bic | String | BIC printed on the invoices |
Media
"medias": [
{
"reference": "media-beach-view",
"media_name": "Beach view",
"path_full": "https://ezus-media.s3.amazonaws.com/media/9a1a8617/1700000000000.jpg",
"object_type": "supplier",
"object_reference": "supplier_reference"
}
]
| Property | Type | Description |
|---|---|---|
| reference | String | The reference given at creation through media-create. When the media was added from Ezus, it is the unique id of the media. Empty for a media of a step |
| media_name | String | The name of the media |
| path_full | String | The URL of the image |
| object_type | String | The type of the object the media is attached to. Possible values: supplier, product, package, subdestination, step. When reading the media library, an empty value means the media is not linked to anything |
| object_reference | String | The reference of the object the media is attached to. Empty when the media is not linked to anything |
Medias
Only the last 10 medias are returned in this object.
"medias": {
"data": [
{
"media_name": "img.jpeg",
"path_full": "https://link-img.jpeg"
}
],
"size": 1
}
| Property | Type | Description |
|---|---|---|
| media_name | String | Title of the media |
| path_full | String | Media URL. This is a pre-signed URL that expires after 30 minutes |
Numbering Counter
A counter of the account, shared by Invoice Numbering and Reference Numbering. Reading it never consumes a number.
{
"counter_name": "MICE",
"format": "$$yyyy$$$$mm$$$$n$$-MICE$$ppp$$",
"counter_size": 5,
"next_number": 12,
"reset": "yearly"
}
| Property | Type | Description |
|---|---|---|
| counter_name | String | Name of the counter. Default when it has none |
| format | String | Pattern of the numbers, as stored, with the placeholders below |
| counter_size | Integer | Minimum number of digits of $$n$$, zero padded: 4 turns 12 into 0012 |
| next_number | Integer | Number the counter will issue next |
| reset | String | When the counter goes back to 1. Possible values: never, monthly (on the 1st of each month), yearly (on January 1st) |
The placeholders of format, replaced when a number is issued:
| Placeholder | Replaced by |
|---|---|
$$yyyy$$ |
Year, 4 digits |
$$yy$$ |
Year, 2 digits |
$$mm$$ |
Month, 2 digits |
$$m$$ |
Month, without leading zero |
$$dd$$ |
Day of the month, 2 digits |
$$d$$ |
Day of the month, without leading zero |
$$n$$ |
The number, padded to counter_size digits |
$$c$$ |
First 3 letters of the client company name, in capitals. Projects only |
$$dest$$ |
First 3 letters of the destination, in capitals. Projects only |
$$p$$ |
Number of travellers. Projects only |
$$pp$$ |
Number of travellers, 2 digits. Projects only |
$$ppp$$ |
Number of travellers, 3 digits. Projects only |
Products
Only the last 10 products are returned in this object.
"products": {
"data": [
{
"reference": "product_reference",
"title": "2-bed room with breakfast"
}
],
"size": 1
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the product |
| title | String | The title of the product |
Project Config
The settings the prices of a project are computed with, returned by GET /project?include=config. Each alternative carries its own; a setting the alternative leaves to the account carries the account value, as default in Account Defaults.
"config": {
"currencies": {
"reference": "EUR",
"projects": "USD",
"library": [
{ "code": "EUR", "name": "Euro", "rate": 1 },
{ "code": "GBP", "name": "Pounds sterling", "rate": 0.87 },
{ "code": "USD", "name": "US dollar", "rate": 2.1 }
]
},
"alternatives": [
{
"reference": "550e8400-e29b-41d4-a716-446655440000",
"alternative_title": "Main Alternative",
"is_main": true,
"default": {
"price_display": "excluded_taxes",
"margin_based_on": "sales_price",
"margin_calculation": "per_product",
"vat_regime": "margin",
"vat_rate": 20,
"vat_rate_margin": 20,
"vat_classic_calculation_mode": "line",
"vat_not_applicable_is_recoverable": false,
"commission_based_on": "purchase_price",
"project_global_supplements": {
"fees": 5,
"fees_type": "percentage",
"discount": 0,
"discount_type": "flat"
},
"purchase_invoices_based_on": "total_forecast_purchase_price"
}
},
{
"reference": "7d2c3a1e-4f5b-4c6d-8e9f-0a1b2c3d4e5f",
"alternative_title": "Alternative 2",
"is_main": false,
"default": {
"price_display": "included_taxes",
"margin_based_on": "sales_price",
"margin_calculation": "global",
"vat_regime": "classic",
"vat_rate": 10,
"vat_rate_margin": 20,
"vat_classic_calculation_mode": "vat_rate",
"vat_not_applicable_is_recoverable": false,
"commission_based_on": "purchase_price",
"project_global_supplements": {
"fees": 150,
"fees_type": "flat",
"discount": 0,
"discount_type": "flat"
},
"purchase_invoices_based_on": "total_forecast_purchase_price"
}
}
]
}
| Property | Type | Description |
|---|---|---|
| currencies | JSON | Currency of the project and the exchange rates frozen on it |
| alternatives | Array | Settings of each alternative, in the order and with the reference of alternatives in the project (Alternatives) |
currencies:
| Property | Type | Description |
|---|---|---|
| reference | String | Code of the reference currency, the one every rate is quoted against |
| projects | String | Code of the sales currency of the project |
| library | Array | The reference first, then the rates frozen on the project in the order they were added, each shaped as a currency of Account Currencies. Only the reference when the project has no rate of its own |
Each alternative:
| Property | Type | Description |
|---|---|---|
| reference | String | Reference of the alternative |
| alternative_title | String | Title of the alternative |
| is_main | Boolean | Whether it is the main alternative |
| default | JSON | Settings the alternative is priced with |
default carries these keys of Account Defaults, with the same possible values:
| Property | Set per alternative |
|---|---|
| price_display | Yes |
| margin_based_on | Yes |
| margin_calculation | Yes |
| vat_regime | Yes |
| vat_rate | Yes |
| vat_rate_margin | No, always the account value |
| vat_classic_calculation_mode | Yes |
| vat_not_applicable_is_recoverable | Yes |
| commission_based_on | No, always the account value |
| project_global_supplements | Yes, always the alternative value. A flat fee or discount is an amount in the currency of the project |
| purchase_invoices_based_on | Yes |
Project Statuses
The statuses a project of the account can take, in three groups. An account that never edited its statuses gets the Ezus default ones.
"project_statuses": {
"ongoing": [
{
"name": "Quote sent",
"reference": "quote_sent",
"color": "#00b3ff"
}
],
"archived": [],
"template": []
}
| Property | Type | Description |
|---|---|---|
| ongoing | Array | Statuses of the projects in progress |
| archived | Array | Statuses of the archived projects |
| template | Array | Statuses of the templates, the projects listed with from_programs_catalog=true on GET /projects |
Each status:
| Property | Type | Description |
|---|---|---|
| name | String | Display name of the status, as info_stage returns it on a project |
| reference | String | Technical name of the status, the value info_stage_reference takes on GET /projects and POST /projects-upsert |
| color | String | Color of the status, hexadecimal. null when none is set |
Reference Numbering
The counters giving a reference to a project, a client or a supplier created without one, each shaped as a Numbering Counter.
"reference_numbering": {
"enabled": true,
"projects": [
{
"counter_name": "MICE",
"format": "$$yyyy$$$$mm$$$$n$$-MICE$$ppp$$",
"counter_size": 5,
"next_number": 12,
"reset": "yearly"
}
],
"clients": [],
"suppliers": []
}
| Property | Type | Description |
|---|---|---|
| enabled | Boolean | Whether the account gives automatic references. When false, the three lists are empty |
| projects | Array | Counters of the projects, the default one first |
| clients | Array | Counters of the clients, the default one first |
| suppliers | Array | Counters of the suppliers, the default one first |
Scopes
One entry per permission of the role of the user, keyed by the permission name, so the keys depend on that role. Each value is a three-digit code, one digit per action, in the order read, edit, delete.
"scopes": {
"projects": "333",
"clients": "310",
"travellers": "333",
"suppliers": "333",
"invoices": "300",
"tasks": "333",
"catalog": "333",
"models": "300",
"library": "333",
"invoices_suppliers": "300",
"territories": "333",
"categories": "333",
"invoices_finalize": "000",
"invoices_stats": "000",
"stripe_payments": "000",
"projects_close": "333",
"steps_catalog": "333",
"settings": "000",
"billing_team": "000",
"export": "333",
"templates_edit": "333",
"client_space": "333"
}
| Digit | Access |
|---|---|
0 |
None |
1 |
Records the user owns |
2 |
Records the user owns, plus the ones nobody owns |
3 |
Full |
"clients": "310" reads as: sees every client, edits only their own, deletes none. A permission that is simply on or off, such as invoices_finalize, is 333 or 000.
The permissions the API serves:
| Permission | Covers |
|---|---|
| projects | Projects |
| clients | Clients |
| travellers | Travellers |
| suppliers | Suppliers |
| invoices | Client invoices and deposits |
| tasks | Tasks |
| catalog | Catalog: products and packages |
| models | Document and email models |
| library | Media library |
| invoices_suppliers | Supplier invoices and their payments |
| territories | Destinations and subdestinations |
| categories | Categories |
| invoices_finalize | Finalizing a client invoice |
| invoices_stats | Invoicing statistics |
| stripe_payments | Stripe payments |
| projects_close | Closing a project |
| steps_catalog | The catalog of steps of a project |
| settings | Account settings |
| billing_team | Subscription, billing and team management |
| export | Exports |
| templates_edit | Documents edition |
| client_space | The client space |
A call outside the scopes of the user returns what that user may see, which can be an empty list, not an error.
Seasons Groups
The preset seasons of the account, one entry per group in the order the account sorts them, each with its seasons in their order. A season carries the keys of a seasonal tariff, ready to send on POST /product-seasons-upsert.
"seasons_groups": [
{
"name": "Summer",
"reference": "summer",
"seasons": [
{
"name": "High season",
"reference": "high_season",
"limit_start": "2026-07-01",
"limit_end": "2026-08-31",
"is_yearly": true
}
]
}
]
| Property | Type | Description |
|---|---|---|
| name | String | Display name of the group |
| reference | String | Technical name of the group, unique in the account |
| seasons | Array | Seasons of the group. Empty when it has none |
Each season:
| Property | Type | Description |
|---|---|---|
| name | String | Display name of the season, the name of a seasonal tariff |
| reference | String | Technical name of the season, unique in the account |
| limit_start | String | Start date of the season, "YYYY-MM-DD". null when none is set |
| limit_end | String | End date of the season, "YYYY-MM-DD". null when none is set |
| is_yearly | Boolean | Whether the season recurs every year: only the day and month of its dates count |
Steps
The steps are sorted by their creation date, with the most recently created appearing first.
"steps": [
{
"reference": "activity_reference",
"sample_step_reference": "sample_step_reference",
"type": "activity",
"name": "activityTitle",
"category": "restaurant",
"date_start": "2024-10-01 10:00:00",
"date_end": "2024-10-01 12:00:00",
"people": 4,
"address": {
"label": "58 Rue de Paradis",
"city": "Paris",
"country": "France",
"zip": "75010",
"geo": {
"x": 48.875761,
"y": 2.348727
}
},
"description": {
"short": "Short description of the activity",
"long": "Long description of the activity"
},
"items": [
{
"reference": "item_reference",
"name": "item_title",
"product_reference": "product_reference",
"supplier_reference": "supplier_reference",
"quantity": 2,
"purchase_price": 150,
"purchase_price_excl_taxes": 125,
"sales_price": 200,
"sales_price_excl_taxes": 166.67,
"is_optional": false,
"notes": "Notes about the item",
"booked": false
}
],
"medias": ["https://image.jpg", "https://image2.jpg"],
"custom_fields": [
{
"name": "CustomField",
"value": "Value"
}
]
}
]
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the activity |
| sample_step_reference | String | The reference of the sample step of the catalog this step was created from. Empty when the step was not created from a sample step, or when that sample step has been deleted. |
| type | String | Type of the step activity accommodation transport or extra |
| name | String | Name of the step |
| category | String | Category of the step |
| date_start | String | Date of the beginning of this step, in a "YYYY-MM-DD HH:MM:SS" format string. If it's empty, the step has no dates. |
| date_end | String | Date of the end of this step, in a "YYYY-MM-DD HH:MM:SS" format string. If it's empty, the step has no dates or no end. |
| people | Number | Number of people |
| address | JSON | JSON object representing the address (Address) of the step, including longitude and latitude. Note: Longitude and latitude are only returned by this step object. |
| description | JSON | JSON object representing the short and long description of the step |
| items | Array | Array of JSON items (Items) |
| medias | Array | Array of strings representing the images URLs associated with the step |
| custom_fields | Array | Array of JSON custom fields (Custom fields) |
Step Categories
The categories a step of the account can take, one list per step type, each with the custom fields its steps carry. Extra steps share the categories of the activity steps, so extra lists the same ones as activity.
"step_categories": {
"accommodation": [
{
"name": "Hotel",
"reference": "hotel",
"is_favorite": true,
"custom_fields": [
{
"name": "Check-in time",
"reference": "check-in-time",
"type": "time",
"options": null,
"default": "15:00",
"description": null
}
]
}
],
"transport": [],
"activity": [],
"extra": []
}
| Property | Type | Description |
|---|---|---|
| accommodation | Array | Categories of the accommodation steps, type accom on POST /project-steps-upsert |
| transport | Array | Categories of the transport steps, type transport on POST /project-steps-upsert |
| activity | Array | Categories of the activity steps, type activity on POST /project-steps-upsert |
| extra | Array | Categories of the extra steps, the same as activity |
Each category:
| Property | Type | Description |
|---|---|---|
| name | String | Display name of the category, as category returns it on GET /project-steps |
| reference | String | Technical name of the category, the category to send on POST /project-steps-upsert with a step of that type |
| is_favorite | Boolean | Whether it is the default category of its step type, the one a step created without category gets |
| custom_fields | Array | Custom fields of the steps of this category, each shaped as a field of Custom Field Definitions, without family. Empty when it has none |
Supplements
The supplements of the project. Today only the main fee and main discount are returned by the API.
"supplements": {
"fees": [
{
"reference": "fee_reference",
"label": "Main fee",
"mode": "flat",
"value": 2000,
"amount": 2000,
"amount_excl_taxes": 1666.67,
"notes": "Some notes"
}
],
"discounts": [
{
"reference": "discount_reference",
"label": "Main discount",
"mode": "percentage",
"value": 10,
"amount": 1000,
"amount_excl_taxes": 833.33,
"notes": "Some notes"
}
]
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the fee/discount. For the main one it is with this format: alternative_reference-main_fee/main_discount |
| label | String | The label of the fee/discount. For the main one it is with this format: Main fee/Main discount. If the project is in global calculation mode: the label will be Global margin for the main fee. |
| mode | String | The mode of the fee/discount. It can be flat or percentage. If the project is in global calculation mode: the mode will be flat for the main fee. |
| value | Number | The value of the fee/discount. If the mode is flat, it represents a fixed amount. If the mode is percentage, it represents a percentage applied to the project sales price. |
| amount | Number | The amount of the fee/discount. If the mode is flat, it is equal to the value. If the mode is percentage, it is calculated as value% of the project sales price. |
| amount_excl_taxes | Number | The amount of the fee/discount excluding taxes. |
| notes | String | Additional notes or comments about the fee/discount. |
Task
"tasks": [
{
"title": "Call the hotel back",
"description": "Confirm the rooming list before the deposit",
"due_at": "2026-10-07",
"is_done": false,
"assignee": {
"email": "tommy@e-corp.com",
"first_name": "Tommy",
"last_name": "Atkins",
"agency": "Paris Agency"
},
"created_by": "None",
"project": {
"reference": "project_reference",
"info_title": "Japan in autumn"
},
"client": "None",
"created_at": "2026-09-30"
}
]
| Property | Type | Description |
|---|---|---|
| title | String | Title of the task |
| description | String | Description of the task. Empty when none |
| due_at | Date | Due date of the task. Format: "YYYY-MM-DD". Empty when the task has no due date |
| is_done | Boolean | true if the task is completed, false otherwise |
| assignee | JSON | JSON object representing the user the task is assigned to (User). None when the task is unassigned |
| created_by | JSON | JSON object representing the user who created the task (User). None when the task was created automatically, for example from a project template |
| project | JSON | JSON object with the reference and the info_title of the project the task is linked to. None when the task is not linked to a project |
| client | JSON | JSON object with the reference and the company_name of the client the task is linked to. None when the task is not linked to a client |
| created_at | Date | Creation date of the task. Format: "YYYY-MM-DD" |
Tags
"tags": [
{
"reference": "partner",
"type": "client",
"name": "Partner"
},
{
"reference": "premium",
"type": "package",
"name": "Premium"
},
{
"reference": "mice",
"type": "product",
"name": "MICE"
},
{
"reference": "mice",
"type": "supplier",
"name": "MICE"
}
]
| Property | Type | Description |
|---|---|---|
| reference | String | The tag reference matches the technical name of the tag |
| type | String | Tag type. Possible values: product, supplier, client, package |
| name | String | Display name of the tag |
Travellers
"travellers": [
{
"reference": "traveller_reference",
"email": "emily.johnson@example.com",
"first_name": "Emily",
"last_name": "Johnson",
"phone": "+1-555-123-4567",
"project_group_reference": "project_group_reference",
"custom_field1": "value1.1",
"custom_field2": "value2.1"
},
{
"reference": "traveller_reference",
"email": "michael.smith@example.com",
"first_name": "Michael",
"last_name": "Smith",
"phone": "+1-555-987-6543",
"project_group_reference": null,
"custom_field1": "value1.2",
"custom_field2": "value2.2"
}
]
reference and project_group_reference are response only: POST project-travellers-create refuses them.
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the traveller. Response only |
| String | The email of the traveller | |
| first_name | String | The first name of the traveller |
| last_name | String | The last name of the traveller |
| phone | String | The phone number of the traveller |
| project_group_reference | String | The reference of the group of the traveller in group mode (GIR) (Groups). null when it has no group. Response only |
| custom_fields | String | The custom fields and the assigned values. Varies with number of custom fields. |
Unattributed
"unattributed": {
"travellers": [
{
"reference": "traveller_reference",
"first_name": "Michael",
"last_name": "Smith",
"email": "michael.smith@example.com"
}
],
"items": [
{
"reference": "item_reference",
"project_step_reference": "project_step_reference",
"name": "item_title"
}
],
"invoices": []
}
What no group of an alternative holds. A line attributed to some groups only is not listed. Every list is empty for an alternative outside group mode (GIR).
| Property | Type | Description |
|---|---|---|
| travellers | Array | Travellers without a group, each with reference, first_name, last_name and email |
| items | Array | Lines attributed to no group, each with reference, project_step_reference and name |
| invoices | Array | Invoices without a group, each with its reference |
Suppliers
Only the last 10 suppliers are returned in this object.
"suppliers": {
"data": [
{
"reference": "supplier_reference",
"company_name": "The best hotel"
}
],
"size": 1
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the supplier |
| company_name | String | The company name of the supplier |
Tariffs
"tariffs": [
{
"reference": "tariff_reference",
"type": "default",
"name": "",
"purchase_price": "100",
"margin_rate": "33.33",
"sales_price": "150",
"limit_start": "",
"limit_end": "",
"is_yearly": false,
"children": [
{
"reference": "tariff_reference",
"type": "custom",
"name": "",
"purchase_price": "100",
"margin_rate": "33.33",
"sales_price": "150",
"limit_start": "0",
"limit_end": "11",
"is_yearly": false
},
{
"reference": "tariff_reference",
"type": "custom",
"name": "",
"purchase_price": "100",
"margin_rate": "23.08",
"sales_price": "130",
"limit_start": "12",
"limit_end": "Infinity",
"is_yearly": false
}
]
},
{
"reference": "tariff_reference",
"type": "season",
"name": "tariff season",
"purchase_price": "100",
"margin_rate": "16.66",
"sales_price": "120",
"limit_start": "2026-05-01",
"limit_end": "2026-08-31",
"is_yearly": true,
"children": [
{
"reference": "tariff_reference",
"type": "custom",
"name": "",
"purchase_price": "100",
"margin_rate": "9.09",
"sales_price": "110",
"limit_start": "0",
"limit_end": "10",
"is_yearly": false
},
{
"reference": "tariff_reference",
"type": "custom",
"name": "",
"purchase_price": "100",
"margin_rate": "16.66",
"sales_price": "120",
"limit_start": "11",
"limit_end": "Infinity",
"is_yearly": false
}
]
}
]
| Property | Type | Description |
|---|---|---|
| reference | String | A unique reference of this tariff |
| type | String | A tariff can be default, custom OR season. |
| name | String | Name of the tariff (only seasonal tariffs have a name) |
| purchase_price | String | Purchase price including taxes |
| margin_rate | String | The margin rate is based on the sales price |
| sales_price | String | Sales price including taxes |
| limit_start | String | Indicates the starting point of a tariff rule either the start date of a seasonal tariff or the lower bound of a level for a custom tariff. |
| limit_end | String | Indicates the end point of a tariff rule either the end date of a seasonal tariff or the upper bound of a level for a custom tariff. When set to Infinity, it designates the final level of a flat-rate or open-ended tariff. |
| is_yearly | Boolean | Indicates if the seasonal tariff recurs every year . This field is only applicable when type is season, For default or custom tariffs, this field is always false. |
| children | Array | Children are sub-tariffs contained by this tariff. They may be seasonal tariff or default tariff when they are flat rate tariff. |
Token
"token": {
"issued_at": "2026-09-19T10:00:00Z",
"expires_at": "2026-09-19T22:00:00Z"
}
| Property | Type | Description |
|---|---|---|
| issued_at | String | When the token was issued, UTC |
| expires_at | String | When the token expires, UTC |
User
One of the following options: None, Everyone, User Group or the following JSON object corresponding to an active Ezus user of this account.
"user": {
"email": "tommy@e-corp.com",
"first_name": "Tommy",
"last_name": "Atkins",
"agency": "Paris Agency"
}
| Property | Type | Description |
|---|---|---|
| String | Email of the user | |
| first_name | String | First name of the user |
| last_name | String | Last name of the user |
| agency | String | User's affiliated agency |
Webhooks
"webhooks": [
{
"reference": "webhook_reference",
"endpoint": "webhook_endpoint",
"events_types": "projects.created,clients.created",
"is_active": "true",
"last_called_at": "2023-01-01 01:01:01"
}
]
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the webhook |
| endpoint | String | The endpoint URL of the webhook |
| events_types | String | The list of events for this endpoint (Events) |
| is_active | String | The status of the webhook true or false |
| last_called_at | String | The webhook last called date in a "YYYY-MM-DD hh:mm:ss" format string |
Events
Basic event information
This section provides an overview of the fundamental details related to a webhook event, including its unique identifier, type, creation timestamp, trigger source, and whether it's a duplication.
{
"id": "event_id",
"object": "event",
"type": "projects.created",
"field": "",
"old_value": "",
"new_value": "",
"created": 1234567890,
"trigger_reference": "pro.ezus.io;projects-create",
"is_duplication": false,
"data": {...}
}
| Property | Type | Description |
|---|---|---|
| id | String | Unique identifier for the event |
| object | String | The object of the event. The event's target object is currently limited to event but in the future, webhooks will become capable of being triggered by various other events. |
| type | String | The type of the event |
| field | String | This is only displayed if the event is an update. The name of the field that was updated. |
| old_value | String | This is only displayed if the event is an update. The previous value of the updated field. |
| new_value | String | This is only displayed if the event is an update. The updated field's new value. |
| created | Number | Time at which the object was created. Measured in seconds since the Unix epoch. |
| trigger_reference | String | The trigger of the event. Indicates the source or origin from which the event was initiated. |
| is_duplication | Boolean | Indicates whether the event originates from a duplication |
| data | String | Detailed information about the event. For more in-depth details, please refer to the sections below. |
projects.created
This event is triggered whenever a project is either created or duplicated.
{
"data": {
"reference": "project_reference",
"info_number": "202306001-P",
"info_title": "Paris fashion week 2024",
"trip_date_in": "2024-03-01",
"trip_date_out": "2024-03-09",
"trip_duration": "9",
"trip_budget": "90000",
"trip_people": "15"
}
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the project |
| info_number | String | File number that appears in the project record. Not to be confused with reference |
| info_title | String | The title of the project |
| trip_date_in | String | Date of the beginning of this alternative, in a "YYYY-MM-DD" format string. If it's empty, the project has no dates. |
| trip_date_out | String | Date of the end of this alternative, in a "YYYY-MM-DD" format string. If it's empty, the project has no dates. |
| trip_duration | String | Number of days this project lasts |
| trip_budget | String | Forecasted budget for the alternative (the one that is entered manually not the actual one) |
| trip_people | String | Number of people |
projects.updated
This event is triggered whenever a project is updated. This event is triggered only by specific fields within projects, including: info_title, info_stage, info_notes, info_number, currency, sales_manager, and projects_manager.
{
"data": {
"reference": "project_reference",
"info_number": "202306001-P",
"info_title": "Paris fashion week 2024"
}
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the project |
| info_number | String | File number that appears in the project record. Not to be confused with reference |
| info_title | String | The title of the project |
clients.created
This event is triggered whenever a client is created.
{
"data": {
"reference": "client_reference",
"info_number": "202306001-C",
"type": "enterprise",
"company_name": "MOKE INTERNATIONAL LIMITED",
"email": "contact@moke-international.com",
"first_name": "Jane",
"last_name": "Doe",
"gender": "Ms",
"phone": "0101010101",
"birth_date": "1986-09-17"
}
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the client |
| info_number | String | File number that appears in the client record. Not to be confused with reference |
| type | String | The type of the client can be either "enterprise" or "individual" |
| company_name | String | Name of the company of the client |
| String | Email of the main contact of the client | |
| first_name | String | First name of the main contact of the client |
| last_name | String | Last name of the main contact of the client |
| gender | String | Mr, Ms or Undefined |
| phone | String | Phone number of the contact as a string |
| birth_date | String | Contact's date of birth in a "YYYY-MM-DD" format string |
clients.updated
This event is triggered whenever a client is updated. This event is triggered only by specific fields within clients, including: company_name, website, vat_number, company_number, info_notes, info_number and user.
{
"data": {
"reference": "client_reference",
"info_number": "202306001-C",
"company_name": "MOKE INTERNATIONAL LIMITED"
}
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the client |
| info_number | String | File number that appears in the client record. Not to be confused with reference |
| company_name | String | Name of the client's company |
invoices.finalized
This event is triggered whenever an invoice is finalized (its stage goes from draft to completed).
{
"data": {
"reference": "invoice_reference",
"info_number": "2023_101010",
"type": "credit_note",
"origin_reference": "origin_reference",
"origin_info_number": "2023_101009",
"stage": "completed",
"created_date": "2023-10-10",
"send_date": "2023-10-10",
"due_date": "2023-10-10",
"currency": "EUR",
"amount_ttc": 1200.0,
"amount_ht": 1000.0,
"vat": 200.0,
"project_reference": "project_reference",
"url": "https://ezus.io/2023_101010.pdf",
"alternative": {
"sort_order": "0",
"title": "Main Alternative"
}
}
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the invoice |
| info_number | String | Title of the invoice |
| type | String | Type of the invoice invoice or credit_note |
| origin_reference | String | This is only displayed if the type of the invoice is a credit_note. The reference of the origin invoice. |
| origin_info_number | String | This is only displayed if the type of the invoice is a credit_note. Title of the origin invoice. |
| stage | String | Stage of the invoice draft completed or paid |
| created_date | String | Date of the creation of this invoice, in a "YYYY-MM-DD" format |
| send_date | String | Sent date of this invoice, in a "YYYY-MM-DD" format |
| due_date | String | Due date of this invoice, in a "YYYY-MM-DD" format |
| currency | String | The ISO 4217 currency code representing the currency you utilize (Link to doc) |
| amount_ttc | Number | Amount of the invoice including taxes |
| amount_ht | Number | Amount of the invoice excluding taxes |
| vat | Number | VAT amount of the invoice |
| project_reference | String | The reference of the project linked to this invoice |
| url | String | URL of the invoice .pdf file |
| alternative | JSON | JSON including: sort_order and title |
invoices_suppliers.attached
This event is triggered whenever a file is added to a supplier invoice.
{
"data": {
"reference": "invoice_supplier_reference",
"has_attachement": true,
"filename": "2023_101010.pdf",
"url": "https://ezus.io/2023_101010.pdf",
"created_date": "2023-10-10",
"due_date": "2023-10-20",
"send_date": "2023-10-15",
"currency": "EUR",
"amount_ttc": 1200.0,
"amount_ht": 1000.0,
"vat": 200.0,
"supplier_reference": "supplier_reference",
"project_reference": "project_reference",
"alternative": {
"sort_order": "0",
"title": "Main Alternative"
}
}
}
| Property | Type | Description |
|---|---|---|
| reference | String | The reference of the supplier invoice |
| has_attachement | Boolean | true if a file is attached (filename and url are both set), false otherwise |
| filename | String | Filename of the supplier invoice |
| url | String | URL of the supplier invoice file |
| created_date | String | Date of the creation of this supplier invoice, in a "YYYY-MM-DD" format |
| due_date | String | Due date of this supplier invoice, in a "YYYY-MM-DD" format |
| send_date | String | Sent date of this supplier invoice, in a "YYYY-MM-DD" format |
| currency | String | The ISO 4217 currency code representing the currency you utilize (Link to doc) |
| amount_ttc | Number | Amount of the supplier invoice including taxes |
| amount_ht | Number | Amount of the supplier invoice excluding taxes |
| vat | Number | VAT amount of the supplier invoice |
| supplier_reference | String | The reference of the supplier linked to this supplier invoice |
| project_reference | String | The reference of the project linked to this supplier invoice |
| alternative | JSON | JSON including: sort_order and title |
Filtering
List endpoints accept query-parameter filters. Each endpoint lists its available filters and labels each one with its type: a plain exact match, a dynamic (text) filter, or a dynamic date filter. Some are additionally flagged as linked-record filters, meaning they only match objects whose linked entity has not been deleted.
Encoding Filter Values
Filter suppliers named
Hotel à 20% & Spa:
curl --get "https://api.ezus.io/suppliers" \
--data-urlencode "company_name=Hotel à 20% & Spa" \
-H "x-api-key: YOUR_API_KEY" \
-H "Authorization: Bearer YOUR_TOKEN"
const params = new URLSearchParams({ company_name: "Hotel à 20% & Spa" });
const response = await fetch(`https://api.ezus.io/suppliers?${params}`, {
headers: {
"x-api-key": "YOUR_API_KEY",
Authorization: "Bearer YOUR_TOKEN",
},
});
Filter values must be URL-encoded, as encodeURIComponent or URLSearchParams do. Hotel à 20% & Spa is sent as company_name=Hotel%20%C3%A0%2020%25%20%26%20Spa.
| Character | Encoded | Sent unencoded |
|---|---|---|
% |
%25 |
HTTP 400 Bad Request with an empty body: the request never reaches the API |
& |
%26 |
Ends the value; the rest is read as another query parameter |
+ |
%2B |
Read as a space |
# |
%23 |
Ends the URL; the rest of the value and every parameter after it are not sent |
| space | %20 |
Rejected by most HTTP clients |
à, é… |
UTF-8 | %C3%A0, %C3%A9… |
A value that is not encoded is not detected: the API answers for the request it received, which is not the one you meant.
%, _ and \ are matched as themselves, never as wildcards: reference_like=A_1 matches A_1, not AB1.
A query parameter whose value is only whitespace (e.g. company_name_like=%20) is refused with an error naming it: {"error": "true", "message": "company_name_like cannot be only whitespace"}.
Linked-Record Filters
Across list endpoints, some filters target a linked record (e.g. the client, project or alternative attached to an invoice) rather than the returned object itself.
By default, a list includes objects whose linked record has been deleted: the object still exists (e.g. an invoice remains even if the client or project linked to it has been deleted).
But a linked-record filter only matches objects whose linked record still exists. As a result, applying such a filter excludes objects attached to a deleted linked record (e.g. filtering invoices on a project start date in June 2026 will not return invoices linked to deleted projects that started in June 2026).
Filtering on a linked-record field therefore narrows results to objects whose linked record is not deleted.
Each endpoint indicates which of its filters are linked-record filters.
Unsupported Filters
A query parameter that an endpoint does not list is ignored. The request still succeeds and returns the same results as without it, with one warning per ignored parameter.
This also applies to a listed filter with an operator that does not exist (e.g. email_foo) or that does not fit its type (e.g. created_date_like).
next_token never raises a warning.
Dynamic Filters
Some filters can be marked as Dynamic filter. When a filter is dynamic, it only accepts String values, and you can append operator suffixes directly to the query parameter name.
Let’s take the email field as an example.
If it’s defined as a dynamic filter, you can use different comparison operators in the query parameter name:
| Operator | Suffix | Description | Example |
|---|---|---|---|
| Equals | Filters that aren’t marked as dynamic default to equals, meaning it will match values exactly | email=contact@moke-international.com |
|
| Equals | _eq |
Exact match | email_eq=contact@moke-international.com |
| Starts with | _starts |
Field value starts with... | email_starts=contact |
| Ends with | _ends |
Field value ends with... | email_ends=international.com |
| Contains | _like |
Field value contains... | email_like=moke |
Dynamic Date Filters
Some date filters can be marked as Dynamic date filter.
They follow the same suffix mechanism as text Dynamic filters, but with date comparison operators. Values must be provided in YYYY-MM-DD format.
| Operator | Suffix | Description | Example |
|---|---|---|---|
| Equals | Filters that aren’t marked as dynamic default to equals, meaning it will match values exactly | created_date=2026-01-15 |
|
| Equals | _eq |
Exact date | created_date_eq=2026-01-15 |
| After | _gt |
Strictly after | created_date_gt=2026-01-01 |
| On or after | _gte |
On or after (incl.) | created_date_gte=2026-01-01 |
| Before | _lt |
Strictly before | created_date_lt=2026-02-01 |
| On or before | _lte |
On or before (incl.) | created_date_lte=2026-01-31 |
A date range is obtained by combining two suffixes, e.g. created_date_gte=2026-01-01&created_date_lte=2026-03-31.
Date Format
All dates in our API follow the YYYY-MM-DD format. Our database stores dates in Central European Time (CET/CEST - UTC+1/UTC+2).
Date format specifications
- The API returns dates without specific time information
- Dates are stored and processed in Paris local time
- Date conversions automatically account for daylight saving time changes
- A date like
2024-12-01represents the full day in Central European Time2024-11-30 23:30:00 UTC+0will be considered as2024-12-01for instance
Date filters
Date filters allow you to retrieve objects based on specific dates or date ranges.
Single date filter:
- Retrieves all objects for a specific date
- Format:
"YYYY-MM-DD"(Year-Month-Day) - Example:
"2024-12-01"will return all objects dated December 1st, 2024
Date range filter:
- Retrieves objects within a specified date range
- Includes both start and end dates
- Format:
"start_date,end_date" - Example:
"2024-12-01,2024-12-31"returns all objects from December 1st to December 31st, 2024
Rate Limits
Daily rate limit
For security reasons, the API allows you to make 10,000 calls per day period. What does this "day period" mean? It means we limit to 10,000 requests per day from the first request made. This limit is called later "daily rate limit" and is reset once the day is over.
Burst rate limit
Additionally, the API is protected by a burst rate limit. This means you can't make more than 100 requests per second.
Warnings
The Ezus API uses the following warning message format in the message field: {code}_{field}. Where:
codeis the warning codefieldis the field name that caused the warning
Multiple warnings are separated by a comma.
The Ezus API uses the following warning codes:
| Warning Code | Meaning |
|---|---|
| skip | A field has been skipped |
Here is a warning message example:
{
"error": "false",
"message": "skip_company_number,skip_vat_number",
"action": "Client successfully updated",
"reference": "client_reference"
}
In this case, the fields company_number and vat_number have been skipped during the update of the client. This is due to the fact that these fields are not used for an individual client type. Therefore, these fields have been ignored and not updated.
Ignored Query Parameters
On a GET endpoint, each query parameter the endpoint does not support (see Unsupported Filters) adds a warning to the message field:
Warning: The filter '{parameter}' does not exist and was ignored
Multiple warnings are separated by a comma. message is absent when every query parameter is supported.
{
"error": "false",
"next_token": "<NEXT_TOKEN>",
"size": 85,
"data_size": 50,
"page": 1,
"suppliers": [...],
"message": "Warning: The filter 'company_name_like' does not exist and was ignored,Warning: The filter 'capacity_like' does not exist and was ignored"
}
In this case, GET suppliers?company_name_like=Tren&capacity_like=10 returned every supplier: neither filter is supported by this endpoint.
Errors
The Ezus API uses the following error codes:
| Error Code | Meaning |
|---|---|
| 200 | error="true" error message explained in the "message" string |
| 400 | Bad Request -- Your request is invalid. |
| 403 | Forbidden -- The request was blocked by our firewall, or an API key is missing or invalid. |
| 500 | Internal Server Error -- We had a problem with our server. Try again later. |
The Ezus API uses the following error messages:
| Error Message | Meaning |
|---|---|
| This <'OBJECT'> has been deleted | The object you try to access has been deleted |
| Forbidden | Your request was rejected due to missing or invalid API key, or blocked by security rules. |
Some errors also carry a type key, a stable code to branch on instead of the message:
| Type | Meaning |
|---|---|
| REFERENCE_ALREADY_EXISTS | mode is create and reference matches an existing object. Nothing is created or updated. |
| REFERENCE_NOT_FOUND | mode is update and reference matches no object. Nothing is created or updated. |
| AMBIGUOUS_EMAIL_REFERENCE | Several clients or suppliers have a primary contact with the email sent as reference. Nothing is created or updated. |