Offers
The following section provides details about the offers endpoint. This endpoint allows users to retrieve all offers associated with their account. The response will include comprehensive information about each offer, including related data such as client information and contact details. This endpoint is useful for users who need an overview of all their active offers and their associated details.
Get all offers for a user
This endpoint retrieves all offers associated with the user identified by the user_id attached to the bearer token. The response includes all related data, which can encompass zero or many offers.
Parameters
- No parameters are needed; the
user_idis extracted from the bearer token.
Example response
{
"data": [
{
"id": "1",
"attributes": {
"user_id": "10",
"company_id": "20",
"name": "Special Offer",
"is_visible": true,
"offer_status": "active",
"is_manually_rejected": false,
"offer_type": "discount",
"language": "English",
"offer_date": "2023-01-01",
"offer_number": "OFF123",
"email_subject": "Your Special Offer",
"characteristic": "Limited Time",
"total_price_once": "100.00",
"total_price_repeat": "10.00",
"is_allowed_to_navigate": true,
"has_email_reminder": true,
"has_mobile_notifications": true,
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-02T12:00:00Z",
"url": "<https://api.example.com/offers/1>",
"draft_url": "<https://api.example.com/offers/1/draft>"
},
"relationships": {
"client": {
"id": "30",
"company_name": "Example Client",
"website_url": "https://www.exampleclient.com",
"email": "client@example.com",
"logo": "https://storage.example.com/logos/client.png",
"phone_number": "+1-234-567-890"
},
"contact": {
"firstname": "John",
"lastname": "Doe",
"gender": "Male",
"email": "john.doe@example.com",
"phone_number": "+1-987-654-3210",
"note": "Important client contact"
},
"optional_opening_video": {
"id": 12,
"name": "Welcome message",
"file": "welcome.mp4",
"file_path": "videos/welcome_1715512345.mp4",
"file_url": "https://storage.example.com/videos/welcome_1715512345.mp4"
}
}
}
// More offer objects
]
}
Notes
- The
user_idis extracted from the bearer token, ensuring that the offers returned are associated with the authenticated user. - The response includes detailed information about each offer, along with related client and contact information.
- Ensure that the bearer token is valid and associated with your account to retrieve the correct offers.
Get offer by id
This endpoint retrieves a single offer based on the provided offer ID. The request checks if the user_id attached to the bearer token matches the user_id associated with the offer.
Parameters
offer_id(string): The unique identifier of the offer being retrieved.
Example Response
{
"id": "1",
"attributes": {
"user_id": "10",
"company_id": "20",
"name": "Special Offer",
"is_visible": true,
"offer_status": "active",
"is_manually_rejected": false,
"offer_type": "discount",
"language": "English",
"offer_date": "2023-01-01",
"offer_number": "OFF123",
"email_subject": "Your Special Offer",
"characteristic": "Limited Time",
"total_price_once": "100.00",
"total_price_repeat": "10.00",
"is_allowed_to_navigate": true,
"has_email_reminder": true,
"has_mobile_notifications": true,
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-02T12:00:00Z",
"url": "https://api.example.com/offers/1",
"draft_url": "https://api.example.com/offers/1/draft"
},
"relationships": {
"client": {
"id": "30",
"company_name": "Example Client",
"website_url": "https://www.exampleclient.com",
"email": "client@example.com",
"logo": "https://storage.example.com/logos/client.png",
"phone_number": "+1-234-567-890"
},
"contact": {
"firstname": "John",
"lastname": "Doe",
"gender": "Male",
"email": "john.doe@example.com",
"phone_number": "+1-987-654-3210",
"note": "Important client contact"
},
"optional_opening_video": {
"id": 12,
"name": "Welcome message",
"file": "welcome.mp4",
"file_path": "videos/welcome_1715512345.mp4",
"file_url": "https://storage.example.com/videos/welcome_1715512345.mp4"
}
}
}
Notes
- The
user_idattached to the bearer token must match theuser_idassociated with the offer. - Ensure that the
offer_idprovided in the request URL is valid and associated with your account. - Only a single offer will be returned based on the provided
offer_id.
Get all notes for an offer
This endpoint retrieves all notes associated with a specific offer, identified by offer_id. The request ensures that the user_id attached to the bearer token matches the user_id associated with the offer.
Parameters
offer_id(string): The unique identifier of the offer for which the notes are being retrieved.
Example Response
{
"data": [
{
"id": "1",
"attributes": {
"offer_id": "123",
"created_by": "user@example.com",
"is_push_notification": true,
"type": "info",
"message": "Initial offer created.",
"is_deleted_app": false,
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-01T12:30:00Z"
}
},
{
"id": "2",
"attributes": {
"offer_id": "123",
"created_by": "user@example.com",
"is_push_notification": false,
"type": "update",
"message": "Offer details updated.",
"is_deleted_app": false,
"created_at": "2023-01-02T12:00:00Z",
"updated_at": "2023-01-02T12:30:00Z"
}
}
// More note objects
]
}
Notes
- The
user_idattached to the bearer token must match theuser_idassociated with the offer. - Ensure that the
offer_idprovided in the request URL is valid and associated with your account. - The response includes detailed information about each note, including the creator, type, and timestamps.
- Only notes associated with the specified
offer_idwill be returned.
Get offer logs
This endpoint retrieves a single offer together with its activity logs (the loggings recorded for the offer), sorted by logged_at in descending order (most recent first). The response also includes the offer's user (creator) and company as relationships. Access is company-based: the company_id of the authenticated user must match the company_id of the offer, so any user can retrieve the logs of offers belonging to their own company.
Parameters
offer_id(string, required): The unique identifier of the offer for which the logs are being retrieved.
Log types
Each log has a type describing the event it represents:
| Type | Description |
|---|---|
is_send | The offer was sent to the contact. |
is_viewed | The offer was opened by the contact (status Opened). |
is_declined | The offer was declined by the contact. |
is_accepted | The offer was accepted by the contact. |
is_manual | A manual log entry added by a user. |
Example response
{
"data": {
"id": "1",
"attributes": {
"user_id": "10",
"company_id": "20",
"name": "Special Offer",
"offer_status": "Accepted",
"offer_number": "OFF123",
"created_at": "2023-01-01T12:00:00Z",
"updated_at": "2023-01-02T12:00:00Z"
},
"relationships": {
"user": {
"id": "10",
"name": "John",
"full_name": "John Doe",
"email": "john.doe@example.com"
},
"company": {
"id": "20",
"name": "Example Company",
"email": "info@examplecompany.com",
"website_url": "https://www.examplecompany.com",
"phone_number": "+1-234-567-890"
},
"logs": [
{
"id": "42",
"type": "is_accepted",
"message": "Offer accepted by the contact.",
"is_push_notification": true,
"created_by": "john.doe@example.com",
"logged_at": "2023-01-02T12:00:00Z",
"created_at": "2023-01-02T12:00:00Z"
},
{
"id": "41",
"type": "is_viewed",
"message": "Offer opened by the contact.",
"is_push_notification": true,
"created_by": "System",
"logged_at": "2023-01-01T14:00:00Z",
"created_at": "2023-01-01T14:00:00Z"
}
]
}
}
}
Notes
- The
company_idattached to the bearer token must match thecompany_idassociated with the offer; otherwise a401 Unauthorizedis returned. - Logs are always ordered by
logged_at, most recent first. created_bycontains the email of the user who triggered the log, orSystemwhen the log was generated automatically.
Get offer logs by external id
This endpoint returns the same payload as Get offer logs, but resolves the offer through the external_id of the ExternalDataSet linked to it, instead of the internal offer_id. It is intended for external integrations that only know their own external_id. Access is company-based: the resolved offer must belong to the same company as the authenticated user.
Parameters
external_id(string, required): The external identifier of theExternalDataSetlinked to the offer.
Example response
The response is identical to Get offer logs — the offer with its user, company and logs relationships, sorted by logged_at (most recent first).
Notes
- If no
ExternalDataSetmatches the givenexternal_id, a422 Unprocessable Entityvalidation error is returned:
{
"message": "No offer was found for the given external id.",
"errors": {
"external_id": ["No offer was found for the given external id."]
}
}
- If the
external_idresolves to an offer that belongs to another company, a401 Unauthorizedis returned. - On success the response is the same shape as
GET /api/offers/{offer_id}/logs.
Send offer
To ensure data integrity and security, we have implemented middleware that performs various validation checks before an offer can be sent. This middleware is executed before processing the API request and applies the following rules:
Validation Rules
- If an offer has been soft deleted, it is no longer valid for processing and cannot be sent.
- The offer can only be sent if the
company_idof the offer matches thecompany_idof the authenticated user making the API request. - This prevents unauthorized access to offers belonging to other companies.
- If an offer has already been accepted or rejected, it cannot be sent again. This ensures that status updates remain consistent and prevents duplicate processing of previously handled offers.
If the
send_dateof the offer has passed, the offer is considered expired and cannot be sent.
This validation logic ensures that only valid and authorized offers can be processed, preventing errors, security risks, and inconsistent data. If you have any questions or need further clarification, please feel free to reach out. 🚀
Toggle mobile notifications
This endpoint toggles the has_mobile_notifications field for a specific offer. When enabled, the user will receive push notifications on their mobile device for events related to this offer (e.g. offer viewed, accepted, declined). When disabled, no mobile push notifications will be sent for this offer.
Parameters
offer_id(string, required): The unique identifier of the offer.
Request body
has_mobile_notifications(boolean, required): Whether mobile push notifications are enabled for this offer.
{
"has_mobile_notifications": false
}
Response
Returns a 200 OK with no content on success.
Notes
- The
user_idattached to the bearer token must match theuser_idassociated with the offer. - Mobile notifications are enabled by default when an offer is created.
Update opening video
This endpoint links a previously uploaded video to a specific offer as its optional opening video. It only updates the opening video field — no other offer fields are affected.
Parameters
offer_id(string, required): The unique identifier of the offer to update.
Request body
Send as application/json.
optional_opening_video(integer, required, nullable): Theidof aVideothat belongs to the same company as the authenticated user. Passnullto detach the current opening video.
{
"optional_opening_video": 12
}
Validation
optional_opening_videomust be sent in the body (it may benull).- When not
null, it must reference an existing video. - The referenced video must belong to the same
company_idas the authenticated user.
Example response
Returns the updated offer using the same shape as GET /api/offers/{offer_id}, including the newly linked video under relationships.optional_opening_video.
{
"data": {
"id": "1",
"attributes": {
"user_id": "10",
"company_id": "20",
"name": "Special Offer",
"..." : "..."
},
"relationships": {
"client": { "...": "..." },
"contact": { "...": "..." },
"optional_opening_video": {
"id": 12,
"name": "Welcome message",
"file": "welcome.mp4",
"file_path": "videos/welcome_1715512345.mp4",
"file_url": "https://storage.example.com/videos/welcome_1715512345.mp4"
}
}
}
}
Notes
- The
user_idattached to the bearer token must match theuser_idassociated with the offer. - Use the Videos endpoint to upload a new video and obtain its
idbefore calling this endpoint.