API for managing profiles, batches, and campaign scheduling in Optimized.App.
To begin utilizing Optimized.App, it's essential to:
Obtain an API Token Access to the API is granted only through a valid API Token. Note: API Tokens can only be created by an organization administrator. You can generate your token via the Organization Settings section, under Integration -> Api Tokens on the Optimized.App dashboard.
Understand Rate and Usage Limits Optimized.App has specific rate and usage limitations. Familiarize yourself with these to ensure uninterrupted service.
Secure Communication Protocol Optimized.App mandates the use of HTTPS-secured communications. Any requests sent via HTTP return an HTTP 301 redirect to the corresponding HTTPS resources.
Response Format All responses from Optimized.App are provided in JSON format, ensuring a standardized and easy-to-parse structure for your applications.
All datetime values in requests and responses are in UTC timezone. Responses are formatted according to ISO 8601 standard (YYYY-MM-DDThh:mm:ss.sssZ).
By following these guidelines, you'll be set to effectively integrate and work with Optimized.App's API.
To begin utilizing Optimized.App, it's essential to:
You must include an API token in each request to the Optimized.App API with the Authorization request header.
Example: Authorization: Bearer [API-TOKEN]
If an API token is missing, malformed, or invalid, you will receive an HTTP 401 Unauthorized response code.
The basic rate limit is 250 requests per minute per user basis. Also, depending on your plan, you may have different usage limits. If you exceed either limit, your request will return an HTTP 429 Too Many Requests status code.
The following set of headers are returned on the response to help you identify your use status:
Header | Description |
---|---|
X-Ratelimit-Limit | The maximum number of requests that the consumer is permitted to make per minute. |
X-Ratelimit-Remaining | The number of requests remaining in the current rate limit window. |
X-Ratelimit-Reset | The time at which the current rate limit window resets in UTC epoch seconds. This header is only present when maximum number of requests has been consumed for time period. |
Endpoint | Description |
---|---|
Profile importing with scheduling | This is a group based rate limit for 10 requests per minute. |
Optimized.App employs standard HTTP response codes to signify the outcome of an API request. Typically, codes within the 2xx range signify a successful operation. Codes within the 4xx range point to an error coming from the provided information (for example, missing a necessary parameter or having invalid data). Codes in the 5xx range are indicative of issues with Optimized.App servers, though these occurrences are uncommon.
HTTP status code | Description |
---|---|
200 | Request was made successfully. |
201 | Request was made successfully and a resource was created. |
400 | The request was rejected, often due to missing a required parameter. |
401 | API token is not valid. |
403 | API token has no permission to perform the request. |
404 | The requested resource does not exist. |
422 | The request was rejected, often due to invalid client data. |
429 | Too many requests hit the API too quickly. We advise implementing an exponential backoff strategy for your requests. |
500 | Something went wrong on our end. |
503 | An unexpected spike in API access traffic. The server is usually operational within a short period of time. If the outage persists or you receive any other form of an HTTP 5XX error, please contact support. |
When a request fails validation, the API will respond with a 422 Unprocessable Entity
status code and a JSON response containing detailed information about the validation errors.
When validation fails for a request, the API will return a JSON response that includes:
message
that summarizes the validation issueserrors
object containing detailed validation error messages organized by field{
"message": "The fail on missing attributes field must be true or false.",
"errors": {
"fail_on_missing_attributes": [
"The fail on missing attributes field must be true or false."
]
}
}
message: A summary of validation errors that occurred. If there are multiple errors, the message will indicate how many additional errors exist beyond the first one mentioned.
errors: An object where:
When validating array elements, the error keys will include the array indices:
{
"message": "The profiles.1.person.email_address must be a valid email address. (and 1 more error)",
"errors": {
"profiles.1.person.email_address": [
"The profiles.1.person.email_address must be a valid email address."
],
"profiles.0.person.phone_number": [
"The profiles.0.person.phone_number field contains an invalid number."
]
}
}
For nested fields using "dot" notation, error keys in the response will maintain this notation for easy identification:
When developing an integration with the Optimized.App API, consider these best practices for handling validation errors:
Always check for the HTTP status code first - a status code of 422 indicates validation errors.
Extract field-specific errors from the errors
object to display targeted feedback to your users.
Display all validation errors to users at once rather than one at a time to improve user experience.
For form submissions, map the error field names in the API response to your form field names for proper error display.
Implement client-side validation that mirrors the API's validation rules to provide faster feedback to users before submitting requests to the API.
By properly handling validation errors, you can create a smoother integration experience with the Optimized.App API and provide clear guidance to users when their inputs need correction.
Optimized.App API uses pagination for endpoints that return collections of resources to improve performance and reduce response sizes. Pagination information is included in the JSON response body and follows a consistent format across all paginated endpoints.
Paginated responses include the following standard fields:
Field | Description |
---|---|
current_page | The current page number |
data | Array containing the actual resource items for the current page |
first_page_url | URL for the first page of results |
from | Position of the first item on the current page |
next_page_url | URL for the next page (null if there is no next page) |
path | Base URL path without query parameters |
per_page | Number of items displayed per page |
prev_page_url | URL for the previous page (null if there is no previous page) |
to | Position of the last item on the current page |
{
"current_page": 1,
"data": [
{
"uuid": "9e072d6f-11af-4a13-a373-924a516d3795",
"metadata": [],
"name": "My Group",
"created_at": "2025-01-22T09:04:02.000000Z",
"updated_at": "2025-01-22T09:04:02.000000Z",
"deleted_at": null
},
{
"uuid": "9e072d6f-0ed2-486a-baca-58f889f55cd4",
"metadata": [],
"name": "My second group",
"created_at": "2025-01-22T09:04:02.000000Z",
"updated_at": "2025-01-22T09:04:02.000000Z",
"deleted_at": null
}
],
"first_page_url": "https://api.optimized.app/v1/my-groups&page=1",
"from": 1,
"next_page_url": null,
"path": "https://api.optimized.app/v1/my-groups",
"per_page": 25,
"prev_page_url": null,
"to": 2
}
You can sort paginated results using the sort
parameter:
GET /v1/my-groups?sort=created_at
For descending order, prefix the field name with a minus sign:
GET /v1/my-groups?sort=-created_at
Always check for null values in next_page_url
and prev_page_url
to determine if there are more pages available.
Use the provided URLs instead of constructing your own to ensure proper formatting and compatibility with API changes.
Implement cache invalidation strategies when working with paginated data that may change frequently.
Be mindful of rate limits when making multiple requests to retrieve all pages of a resource. Implement appropriate backoff strategies if necessary.
https://docs.optimized.app/_mock/api/
https://api.optimized.app/
Creates a new batch of profiles with scheduling information.
This endpoint has a special rate limit of 10 requests per minute per group.
This endpoint may fail with a validation error (HTTP 422). See the Errors section for details on error response format.
Common validation errors include: Duplicate or non-unique external_id
, invalid phone number / email address format
Optional. Profile tag information for the batch. If missing, a new one will be created automatically.
Optional. Profile tag information for the batch. If missing, a new one will be created automatically.
Array of profile objects to be created in this batch. Limit: You can include up to 50 profiles in a single request.
External identifier for the profile. Must be unique within your organization.
Optional. Array of custom attributes for the profile.
By default, any attribute that does not already exist will be created automatically.
If fail_on_missing_attributes
is set to true
, then all attributes listed here must already exist in the system (created via the UI or API); otherwise, the request will fail with a validation error.
Optional. Scheduling information for the batch. If omitted, the batch will be imported without scheduling.
If true, all attributes must already exist in the system. If any attribute does not exist (i.e., has not been created from the UI or via the API), the request will fail with a validation errors.
If false or omitted, all missing attributes will be created automatically.
https://docs.optimized.app/_mock/api/v1/groups/{GROUP_ID}/batches
https://api.optimized.app/v1/groups/{GROUP_ID}/batches
curl -i -X POST \
'https://docs.optimized.app/_mock/api/v1/groups/{GROUP_ID}/batches' \
-H 'Authorization: Bearer <YOUR_API Token_HERE>' \
-H 'Content-Type: application/json' \
-d '{
"profile_tag": {
"name": "string"
},
"profiles": [
{
"external_id": "string",
"person": {
"first_name": "string",
"last_name": "string",
"email_address": "user@example.com",
"phone_number": "string"
},
"attributes": [
{
"name": "string",
"value": "string"
}
]
}
],
"schedule": {
"start_at": "2019-08-24T14:15:22Z",
"campaign": {
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f"
}
},
"fail_on_missing_attributes": false
}'
Batch created successfully
List of profiles created in this batch
Timestamp when the batch was last updated
Timestamp when the batch was created
Information about the profile tag for this batch. In the Optimized.App UI, a profile tag is referred to as a "Contact list". If this field is not provided, a new Contact list will be created automatically and a name will be generated by the system. Use this object to associate the batch with an existing Contact list or to create a new one with a custom name.
{ "metadata": [], "profiles": [ { … } ], "uuid": "9ed84352-4652-4892-9fdc-cd0e1738d432", "updated_at": "2025-05-06T07:33:15.000000Z", "created_at": "2025-05-06T07:33:15.000000Z", "group": { "uuid": "9e072d6f-0ed2-486a-baca-58f889f55cd4", "metadata": [], "name": "My group", "created_at": "2025-01-22T09:04:02.000000Z", "updated_at": "2025-01-22T09:04:02.000000Z", "deleted_at": null, "type": { … } }, "campaign": { "uuid": "9e679c93-ff33-4b1e-bfad-1ac77afe1aef", "status": "untested", "name": "Voice with question", "description": "My complicated voice with question campaign", "metadata": [], "created_at": "2025-03-11T07:34:17.000000Z", "updated_at": "2025-04-08T06:28:10.000000Z", "deleted_at": null, "hidden_at": null, "view": "broadcast", "revision": 2 }, "profile_tag": { "name": "Voice with question - 202505060733 - e39f2636", "type": "basic", "is_anonymized": false, "uuid": "9ed84352-3b85-4018-a097-e4e15ff3b127", "updated_at": "2025-05-06T07:33:15.000000Z", "created_at": "2025-05-06T07:33:15.000000Z" }, "schedule": { "metadata": [], "status": "scheduled", "start_at": "2025-05-06T07:33:15.000000Z", "uuid": "9ed84352-453d-4a9d-82ad-a71062f44596", "updated_at": "2025-05-06T07:33:15.000000Z", "created_at": "2025-05-06T07:33:15.000000Z" } }