openapi: 3.1.0 info: version: 25.1126.6886238 x-version-timestamp: 2025-11-26 19:10:23+00:00 title: Addresses Introduction Account Addresses Custom API Entries API description: 'The Addresses API allows you to organize account addresses. Addresses are a sub-resource of `account` resources, an account can have multiple addresses, such as home, work, and neighbour. You can use an account address with either [client_credentials access token](/docs/api/authentication/create-an-access-token) or a combination of [implicit access token](/docs/api/authentication/create-an-access-token) and [Account Management authentication](/docs/api/accounts/post-v-2-account-members-tokens) token. ' contact: name: Elastic Path url: https://www.elasticpath.com email: support@elasticpath.com license: url: https://elasticpath.dev name: MIT servers: - url: https://useast.api.elasticpath.com description: US East - url: https://euwest.api.elasticpath.com description: EU West security: - BearerToken: [] tags: - name: Custom API Entries description: "A **Custom API Entry** is a specific instance of a resource, such as a single wishlist in a Custom API for wishlists.\n\nCustom API Entries can be accessed in two different ways, via the **extension** endpoint, or the **settings** endpoint:\n\n* Extension Endpoint: `/v2/extensions/{custom-api-slug}` - This is the primary endpoint created for use. Most clients should use this endpoint as it adheres to the semantics of the configuration. Retrieve the [OpenAPI Specifications](/docs/api/commerce-extensions/get-open-api-specification) to learn how to interact with this endpoint.\n* Settings Endpoint: `/v2/settings/extensions/custom-apis/{custom-api-id}/entries/` - This endpoint should only be used in cases where you want to interact with your Custom APIs in a generic way in an admin capacity.\n\nCurrently, the distinction between these endpoints is minimal. The extension endpoint uses a slug in the URL path, and the settings endpoint uses an ID. For most use cases involving the new Custom API, we recommend using the extension endpoint.\n\nConceptually, the settings endpoint is analogous to reflection in most programming languages. You use it when you want to operate in a generic way. For example, we used the settings endpoint to build Commerce Manager. Another example is if you need to import and export various types of data from CSV files. Instead of writing multiple scripts for different extension endpoints, you can write one script that operates on the settings endpoint.\n\n## Events\n\nYou can integrate Commerce Extensions with your external systems by observing the appropriate events. For more information, see [Integrations](/docs/api/integrations/integrations-introduction).\n\nGiven you have a Custom API with `api_type` of `wishlist_ext` and you want to perform additional processing when an action is taken, like when a wishlist is created:\n\n```bash\ncurl -X POST https://useast.api.elasticpath.com/v2/extensions/wishlists \\\n -H \"Authorization: Bearer XXXX\" \\\n -H \"Content-Type: application/json\" \\\n -d $ {\n \"data\": {\n \"type\": \"wishlist_ext\",\n \"name\": \"My Wishlist\",\n \"items_count\": 0,\n \"keep_purchased\": false\n }\n }\n```\n\nWhen you [create an integration](/docs/api/integrations/create-integration) with `wishlist_ext.created` in `observes` field.\nThen the configured `webhook` or `aws_sqs` will receive the appropriate message.\n\nYou can configure integrations to observe the following events for your Custom API Entries:\n* Created\n* Updated\n* Deleted\n" paths: /v2/settings/extensions/custom-apis/{custom-api-id}/entries: parameters: - $ref: '#/components/parameters/CustomAPIID' post: tags: - Custom API Entries summary: Create a Custom API Entry operationId: CreateACustomAPIEntry description: Create a Custom API Entry requestBody: $ref: '#/components/requestBodies/CreateCustomAPIEntry' responses: '201': $ref: '#/components/responses/CustomAPIEntry' '400': $ref: '#/components/responses/ValidationError' '403': $ref: '#/components/responses/ForbiddenError' '409': $ref: '#/components/responses/ConflictError' '413': $ref: '#/components/responses/PayloadTooLargeError' description: Payload Too Large. The total size of a Custom API Entry must not exceed 64KB. '500': $ref: '#/components/responses/InternalServerError' '503': $ref: '#/components/responses/ServiceUnavailable' get: tags: - Custom API Entries summary: List Custom API Entries operationId: ListCustomAPIEntries description: 'Retrieves a list of Custom API Entries ## Filtering The following operators and attributes are available for [filtering](/guides/Getting-Started/filtering) all Custom API Entries: | Attribute | Operators | Example | |---------------|-------------------------------|-----------------------------------------------| | `id` | `lt`,`le`,`eq`,`gt`,`ge`,`in` | `eq(id,859aeba1-03c2-4822-bd4c-89afce93d7eb)` | | `created_at` | `lt`,`le`,`eq`,`gt`,`ge` | `ge(created_at,2024-04-29T00:00:00.000Z)` | | `updated_at` | `lt`,`le`,`eq`,`gt`,`ge` | `le(updated_at,2024-04-29T00:00:00.000Z)` | The following operators and attributes may be available for filtering Custom API Entries depending on how the [Custom Fields](/docs/api/commerce-extensions/create-a-custom-field) for that Custom API are configured. | Field type | Operators | |------------|-----------------------------------------------------------| | `string` | `lt`,`le`,`eq`,`gt`,`ge`,`in`,`is_null`,`like` | | `integer` | `lt`,`le`,`eq`,`gt`,`ge`,`in`,`is_null` | | `float` | `lt`,`le`,`gt`,`ge`,`in`,`is_null` | | `boolean` | `eq`,`is_null` | | `list` | `contains`,`contains_any`,`is_null`,`contains_all`(typed) | Given there is a Custom Field with `"slug": "name"` and `"field_type": "string"`. When you get all Custom API Entries with query parameter: `?filter=like(name,*wish*)`. Then you will get all Custom API Entries where `name` contains the string `wish`. :::warn For performance reasons, the `is_null` search operator will **NOT** match entries for a custom_field where the custom_entry was last updated before the custom_field existed. Updating the entry will cause the field to exist and match properly. ::: ## Sorting The following attributes are available for sorting. When specified, the results are sorted in ascending order based on the value of the field. To sort in descending order, prefix the attribute with `-`, for example, `-updated_at`. The default sort order is `created_at` in descending order. - `id` - `created_at` - `updated_at` ## Query Optimization When working with large data sets, the following practices help reduce query latency and avoid timeouts. ### Choose the right `page[total_method]` By default, every list request calculates a `lower_bound` total, which counts up to 10,000 matching records. If you only need to know whether a next page exists (for example, in an infinite-scroll UI), set `page[total_method]=observed`. This skips the full count and only checks for one record beyond the current page, which can significantly reduce response times on large data sets. | Method | Behavior | Best for | |----------------|---------------------------------------------------------------------------|--------------------------------------------| | `lower_bound` | Counts up to 10,000 records; reports exact total or indicates lower bound | Displaying a total count to users | | `observed` | Checks only if a next page exists beyond the current offset and limit | Infinite scroll, cursor-style pagination | ### Skip sorting when order doesn''t matter Setting `sort=null` disables sorting entirely. If your use case does not require a specific order (for example, background sync jobs), this avoids the overhead of ordering results and can improve throughput. ### Narrow your filters Queries that filter on Custom Fields are more efficient when the filter is selective. Prefer exact-match operators (`eq`, `in`) over range or wildcard operators (`like`, `lt`/`le`/`gt`/`ge`) where possible, and combine multiple filters to reduce the result set early. ' parameters: - $ref: '#/components/parameters/PageOffset' - $ref: '#/components/parameters/PageLimit' - $ref: '#/components/parameters/PageTotalMethod' - $ref: '#/components/parameters/Filter' - $ref: '#/components/parameters/CustomAPIEntrySort' - name: timeout description: 'Specifies how long in milliseconds the request should be allowed to take. The service will return a 422 if the request takes longer than the specified timeout. ' in: query schema: type: integer minimum: 1 maximum: 20000 responses: '200': $ref: '#/components/responses/ListOfCustomAPIEntries' '400': $ref: '#/components/responses/BadFilterError' '403': $ref: '#/components/responses/ForbiddenError' '422': $ref: '#/components/responses/UnprocessableContentError' '500': $ref: '#/components/responses/InternalServerError' /v2/settings/extensions/custom-apis/{custom-api-id}/entries/{custom-api-entry-id}: parameters: - $ref: '#/components/parameters/CustomAPIID' - $ref: '#/components/parameters/CustomAPIEntryID' get: tags: - Custom API Entries summary: Get a Custom API Entry operationId: GetACustomEntry description: Get a Custom API Entry responses: '200': $ref: '#/components/responses/CustomAPIEntry' '400': $ref: '#/components/responses/ValidationError' '403': $ref: '#/components/responses/ForbiddenError' '404': $ref: '#/components/responses/NotFoundError' '500': $ref: '#/components/responses/InternalServerError' put: tags: - Custom API Entries summary: Update a Custom API Entry operationId: UpdateACustomEntry description: Update a Custom API Entry parameters: - $ref: '#/components/parameters/IfMatch' requestBody: $ref: '#/components/requestBodies/UpdateCustomAPIEntry' responses: '200': $ref: '#/components/responses/CustomAPIEntry' '201': $ref: '#/components/responses/CustomAPIEntry' '400': $ref: '#/components/responses/ValidationError' '403': $ref: '#/components/responses/ForbiddenError' '404': $ref: '#/components/responses/NotFoundError' '409': $ref: '#/components/responses/ConflictError' '412': $ref: '#/components/responses/PreConditionError' '413': $ref: '#/components/responses/PayloadTooLargeError' description: Payload Too Large. The total size of a Custom API Entry must not exceed 64KB. '500': $ref: '#/components/responses/InternalServerError' '503': $ref: '#/components/responses/ServiceUnavailable' delete: tags: - Custom API Entries summary: Delete a Custom API Entry operationId: DeleteACustomEntry description: Delete a Custom API Entry parameters: - $ref: '#/components/parameters/IfMatch' responses: '204': description: No Content '400': $ref: '#/components/responses/ValidationError' '403': $ref: '#/components/responses/ForbiddenError' '404': $ref: '#/components/responses/NotFoundError' '412': $ref: '#/components/responses/PreConditionError' '500': $ref: '#/components/responses/InternalServerError' '503': $ref: '#/components/responses/ServiceUnavailable' components: parameters: PageOffset: name: page[offset] description: The current offset by number of records, not pages. Offset is zero-based. The maximum records you can offset is 10,000. If no page size is set, the [page length](/docs/api/settings/settings-introduction#page-length) store setting is used. in: query required: false schema: type: integer format: int64 minimum: 0 maximum: 10000 example: 0 Filter: name: filter in: query required: false description: Filter attributes. For more information, see the [Filtering](/guides/Getting-Started/filtering) section. schema: type: string format: string example: eq(name,"My Wishlist") PageLimit: name: page[limit] description: The maximum number of records per page for this response. You can set this value up to 100. If no page size is set, the [page length](/docs/api/settings/settings-introduction#page-length) store setting is used. in: query required: false schema: type: integer format: int64 minimum: 0 example: 100 PageTotalMethod: name: page[total_method] description: 'The method used to calculate the total number of matching entries in the response. ' in: query required: false schema: type: string enum: - lower_bound - observed default: lower_bound x-enumDescriptions: lower_bound: 'Restricts the count of records to at most 10,000. If there are <=10,000 records, the response will indicate it is an exact total, otherwise it will indicate lower_bound. ' observed: 'Restricts the count of record to check only if there is a next page. For example if your page[offset] is 0, and page[limit] is 25, and there are 200 records, then with page[total_method]=observed, the response will indicate there are 26, so that the client knows there are more records. ' CustomAPIEntryID: name: custom-api-entry-id description: The unique identifier of the Custom API Entry. in: path required: true schema: type: string format: uuid example: 7e067539-6f6c-46e1-8c55-940031b36c6a IfMatch: name: If-Match description: 'When If-Match is set, the value must be W/"{etag_id}". If the value of the header matches, the request completes. If not, HTTP 412 Precondition Failed is returned. ' in: header required: true schema: type: string format: string CustomAPIID: name: custom-api-id description: The unique identifier of the Custom API. in: path required: true schema: type: string format: uuid example: 3fa85f64-5717-4562-b3fc-2c963f66afa6 CustomAPIEntrySort: name: sort in: query description: 'Specifies the order in which Custom API Entries will be returned. For more information, see [Sorting](/guides/Getting-Started/sorting). ' required: false schema: type: string default: -created_at enum: - id - -id - created_at - -created_at - updated_at - -updated_at - 'null' example: id x-enumDescriptions: id: Sort by UUID string in ascending order -id: Sort by UUID string in descending order created_at: Sort chronologically from oldest to newest creation date -created_at: Sort chronologically from newest to oldest creation date updated_at: Sort chronologically from oldest to newest update date -updated_at: Sort chronologically from newest to oldest update date 'null': Does not apply any sorting (may improve performance if you don't care about sort) responses: ListOfCustomAPIEntries: description: List of Custom API Entries content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/CustomAPIEntry' meta: $ref: '#/components/schemas/PaginationMeta' links: $ref: '#/components/schemas/PaginationLinks' ForbiddenError: description: Forbidden. You do not have permission to access this resource. content: application/json: schema: $ref: '#/components/schemas/Errors' examples: Forbidden Access: summary: Forbidden error value: "{\n \"errors\": [\n {\n \"title\": \"Forbidden\",\n \"status\": \"403\",\n \"detail\": \"You do not have permission to access this resource.\"\n }\n ]\n}\n" NotFoundError: description: Not found. The requested entity does not exist. content: application/json: schema: $ref: '#/components/schemas/Errors' examples: Not Found: summary: Requested entity not found value: "{\n \"errors\": [\n {\n \"title\": \"Not Found\",\n \"status\": \"404\",\n \"detail\": \"Not found\"\n }\n ]\n}\n" ConflictError: description: Unable to perform the operation at this time. content: application/json: schema: $ref: '#/components/schemas/Errors' examples: Duplicate Custom API: summary: Duplicate Custom API value: "{\n \"errors\": [\n {\n \"title\": \"Conflict\",\n \"status\": \"409\",\n \"detail\": \"custom_api with the given api_type already exists\"\n }\n ]\n}\n" Duplicate Custom Field: summary: Duplicate Custom Field value: "{\n \"errors\": [\n {\n \"title\": \"Conflict\",\n \"status\": \"409\",\n \"detail\": \"custom_field with the given slug already exists\"\n }\n ]\n}\n" ValidationError: description: Bad request. The request failed validation. content: application/json: schema: $ref: '#/components/schemas/Errors' examples: Missing Name: summary: Required field missing value: "{\n \"errors\": [\n {\n \"title\": \"Bad Request\",\n \"status\": \"400\",\n \"detail\": \"The field 'name' is required.\"\n }\n ]\n}\n" ServiceUnavailable: description: The service is temporarily unavailable. This request can be safely retried. content: application/json: schema: $ref: '#/components/schemas/Errors' examples: Service Unavailable: summary: Service Unavailable value: "{\n \"errors\": [\n {\n \"detail\": \"An unknown error occurred\",\n \"status\": \"503\",\n \"title\": \"Service Unavailable\"\n }\n ]\n}\n" UnprocessableContentError: description: 'Unprocessable Content. The server couldn''t satisfy your request, most likely due to a timeout. ' content: application/json: schema: $ref: '#/components/schemas/Errors' examples: Unprocessable Content: summary: Unprocessable content value: "{\n \"errors\": [\n {\n \"title\": \"Unprocessable Content\",\n \"status\": \"422\",\n \"detail\": \"request timed out after 20000 ms.\"\n }\n ]\n}\n" InternalServerError: description: Internal server error. There was a system failure in the platform. content: application/json: schema: $ref: '#/components/schemas/Errors' examples: Internal Server Error: summary: Internal server error value: "{\n \"errors\": [\n {\n \"title\": \"Internal Server Error\",\n \"status\": \"500\",\n \"detail\": \"there was a problem processing your request\"\n }\n ]\n}\n" BadFilterError: description: Bad request. The request failed validation. content: application/json: schema: $ref: '#/components/schemas/Errors' examples: Bad Filter: summary: Invalid field specified for filter value: "{\n \"errors\": [\n {\n \"detail\": \"Invalid filter: unknown field [version] specified in search filter, allowed fields are [api_type created_at description id name slug updated_at]\",\n \"status\": \"400\",\n \"title\": \"Bad Request\"\n }\n ]\n}\n" PayloadTooLargeError: description: Payload Too Large. content: application/json: schema: $ref: '#/components/schemas/Errors' examples: Payload Too Large: summary: Requested entity too large value: "{\n \"errors\": [\n {\n \"title\": \"Request Entity Too Large\",\n \"status\": \"413\",\n \"detail\": \"Maximum entry size reached.\"\n }\n ]\n}\n" PreConditionError: description: Precondition Failed. content: application/json: schema: $ref: '#/components/schemas/Errors' examples: Precondition Failed: summary: Provided ETag does not match the current ETag. value: "{\n \"errors\": [\n {\n \"title\": \"Precondition Failed\",\n \"status\": \"412\",\n \"detail\": \"The provided ETag 'W/\\\"4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a\\\"', does not match the current ETag 'W/\\\"ef2d127de37b942baad06145e54b0c619a1f22327b2ebbcfbec78f5564afe39d\\\"'.\"\n }\n ]\n}\n" CustomAPIEntry: description: A Custom API Entry headers: ETag: description: 'A unique identifier representing the current version of the resource. When the resource changes, the ETag value will also change. The ETag hash will be the same value as `etag_id`, and is marked as a weak entity tag string. For example: etag: W/"5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9", etag_id: 5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9 ' schema: type: string content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/CustomAPIEntry' examples: Custom API Entry: summary: Default Wishlist value: data: id: 7e067539-6f6c-46e1-8c55-940031b36c6a type: wishlist_ext name: My Wishlist items_count: 0 keep_purchased: false tags: - birthday - gifts links: self: /v2/extensions/wishlists/7e067539-6f6c-46e1-8c55-940031b36c6a meta: timestamps: created_at: '2017-01-10T11:41:19.244Z' updated_at: '2017-01-10T11:41:19.244Z' resource_version": 0 data_size": 6 etag_id": 5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9 schemas: Timestamps: type: object properties: created_at: type: string description: Specifies the date the entity is created. example: '2017-01-10T11:41:19.244Z' updated_at: type: string description: Specifies the date the entity is last updated. example: '2017-01-10T11:41:19.244Z' Meta: type: object properties: timestamps: $ref: '#/components/schemas/Timestamps' Errors: required: - errors properties: errors: type: array items: type: object required: - status - title properties: status: type: string description: The HTTP response code of the error. format: string examples: - '400' title: type: string description: A brief summary of the error. examples: - Bad Request detail: type: string description: Optional additional detail about the error. examples: - The field 'name' is required LinkURI: type: - string - 'null' format: uri CustomAPIEntry: type: object additionalProperties: true properties: id: type: string description: The unique identifier for the Custom API Entry. format: uuid type: type: string description: 'Specifies the type of the resource object, use the `api_type` of the [Custom API](/docs/api/commerce-extensions/create-a-custom-api) for Custom API Entry. ' examples: - wishlist_ext links: type: object properties: self: $ref: '#/components/schemas/LinkURI' description: Specifies the URI of the Custom API Entry. example: /v2/extensions/wishlists/7e067539-6f6c-46e1-8c55-940031b36c6a meta: allOf: - $ref: '#/components/schemas/Meta' - type: object properties: data_size: type: integer description: 'The approximate size of the data, used to enforce size limits as this value must not exceed 64 KiB. The exact calculation is intentionally unspecified to allow storage optimizations. This value will always be less than or equal to the size of the JSON representation of all field values. ' default: 0 example: 6 resource_version: type: integer description: 'A unique identifier representing the current version of the resource. When the resource changes, the `resource_version` value will also change. ' default: 0 example: 4 etag_id: type: string description: 'A unique identifier representing the current version of the resource that is a hashed string. When the resource changes, the `etag_id` will also change. ' example: 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b PaginationMeta: type: object properties: results: type: object properties: total: type: integer description: Total number of results for the entire collection. total_method: type: string description: The method used to calculate the total number results. enum: - exact - lower_bound - observed x-enumDescriptions: exact: Indicates that the total is an exact count of results lower_bound: When there are more than 10,000 results, we stop counting at 10,000 and report that the count is a lower_bound. observed: Will indicate if there is at least one more result past the current page, this is the highest performing option as it doesn't require an extra call. page: type: object properties: limit: type: integer description: The maximum number of records for all pages. example: 100 offset: type: integer description: The current offset by number of pages. example: 0 current: type: integer description: The current number of pages. example: 1 total: type: integer description: The total number of pages. example: 1 PaginationLinks: type: object properties: current: $ref: '#/components/schemas/LinkURI' description: Always the current page. example: /v2/settings/custom-apis?page[offset]=0&page[limit]=100 first: $ref: '#/components/schemas/LinkURI' description: Always the first page. example: /v2/settings/custom-apis?page[offset]=0&page[limit]=100 last: $ref: '#/components/schemas/LinkURI' description: Always `null` if there is only one page. example: /v2/settings/custom-apis?page[offset]=0&page[limit]=100 next: $ref: '#/components/schemas/LinkURI' description: Always `null` if there is only one page. example: null prev: $ref: '#/components/schemas/LinkURI' description: Always `null` if on the first page. example: null requestBodies: CreateCustomAPIEntry: content: application/json: schema: type: object required: - data properties: data: type: object required: - type additionalProperties: true properties: type: type: string description: 'Specifies the type of the resource object, use the `api_type` of the [Custom API](/docs/api/commerce-extensions/create-a-custom-api) for Custom API Entry. ' examples: - wishlist_ext examples: Create Example: summary: Create a Wishlist value: data: type: wishlist_ext name: My Wishlist items_count: 0 keep_purchased: false tags: - birthday - gifts UpdateCustomAPIEntry: content: application/json: schema: type: object required: - data properties: data: type: object required: - type additionalProperties: true properties: type: type: string description: 'Specifies the type of the resource object, use the `api_type` of the [Custom API](/docs/api/commerce-extensions/create-a-custom-api) for Custom API Entry. ' examples: - wishlist_ext examples: Update Example: summary: Update a Wishlist value: data: type: wishlist_ext name: My Wishlist items_count: 1 keep_purchased: false tags: - birthday - gifts - priority securitySchemes: BearerToken: type: http scheme: bearer