Skip to main content

Custom Sales Integration

The Custom Sales Integration connects an external sales channel, marketplace, ERP, or order source to Endless through the GraphQL API. It gives the connected system controlled access to create and maintain sales orders while reading the product, inventory, carrier, and channel information needed to build those orders.

This guide explains the integration's role, setup, and recommended operating model. The API reference is the source of truth for available operations, arguments, fields, types, and response shapes.

When to use it

Use a Custom Sales Integration when orders originate outside Endless and no managed connector exists for the source system. Common uses include:

  • importing orders from a marketplace or ecommerce platform
  • receiving wholesale or business-to-business orders from an ERP
  • creating orders from a custom storefront or internal sales tool
  • keeping externally sourced order details and statuses synchronized
  • reading Endless product and inventory data for the sales experience

This integration is intended for sales and order-source workflows. Use a Custom Product Integration for catalog management, a Custom Fulfillment Integration for warehouse execution, or a Custom Data Integration when a system only needs to read data.

The API reference is the source of truth

Use this guide to understand the workflow and use the API reference to build against the current schema. Confirm every operation, required input, enum, and return field there before implementing it.

Every order must identify its integration and sales channel

When creating an order, a Custom Sales Integration must provide both:

  • sourceIntegrationId: the ID of the Custom Sales integration record that is creating the order
  • salesChannelId: the ID of the Endless sales channel that the order belongs to

Use the integration record ID—not the access token, API key ID, or API client ID. Without sourceIntegrationId, Endless cannot reliably attribute the order to the integration or apply the correct source and fulfillment-plan behavior. salesChannelId is also required and must reference an existing sales channel in the same company.

Use originOrderId for the order's stable identifier in the source system. originOrderId identifies the external order; it does not replace sourceIntegrationId, which identifies the integration that created it.

These fields belong in the order creation input. Confirm their current placement and types in the API reference.

Decide how orders are managed

Before building the connection, define the responsibilities of the external sales system and Endless:

  • which system creates the order
  • which Sales Order fields the source will keep synchronized
  • whether the source supplies the initial Fulfillment Orders
  • how cancellations, holds, and status changes move between systems
  • which external identifier uniquely identifies an order
  • how products, sales channels, carriers, and services are mapped
  • how failed or delayed updates are reconciled

Users can edit a sourced Sales Order in Endless without disconnecting this integration. The integration may also supply Fulfillment Orders, or they may be created and managed in Endless. Either way, those Fulfillment Orders are passed to a fulfillment service for processing.

Design reconciliation field by field. If the same Sales Order field can be changed in both systems, decide which value should win on the next source update.

Create the integration

You need permission to manage integrations for your company.

  1. In Endless, open Integrations.
  2. Select Add integration.
  3. Under Custom Integrations, select Custom Sales.
  4. Give the integration a name that identifies the order source.
  5. Select Create & generate credentials.
  6. Save the generated credentials in a password manager or secrets vault before closing the window.

Endless generates an access token, API key, and API secret. The access token is the credential used to authenticate the GraphQL requests described in this guide. The API key and API secret are only displayed when the integration is created or its credentials are regenerated, so save all three values when they are shown.

Create a separate integration for each order source when practical. Separate credentials and integration identities make attribution, troubleshooting, and rotation safer.

Connect to the GraphQL API

Send GraphQL requests as HTTP POST requests to the endpoint shown with the integration. The production endpoint is:

https://api.endlesscommerce.com/graphql

Include these headers with every request:

HeaderValue
Content-Typeapplication/json
X-EC-Access-TokenThe integration's access token
X-Company-IdYour Endless company ID or handle

Do not add Bearer before the value in X-EC-Access-Token.

Test the connection

Use a schema-independent query to check the endpoint, credentials, and company context:

curl --request POST \
--url https://api.endlesscommerce.com/graphql \
--header 'Content-Type: application/json' \
--header 'X-EC-Access-Token: YOUR_ACCESS_TOKEN' \
--header 'X-Company-Id: YOUR_COMPANY_ID' \
--data '{"query":"query ConnectionCheck { __typename }"}'

A successful response includes "__typename": "Query". This confirms the connection, but it does not validate a particular order operation.

Build the order workflow

A reliable sales integration usually follows this sequence:

  1. Detect a new or changed order in the source system.
  2. Resolve the related products, sales channel, carrier service, and other references required by the current API schema.
  3. Create the order with the Custom Sales integration ID in sourceIntegrationId and the mapped Endless sales channel ID in salesChannelId.
  4. Store the Endless order identifier alongside the source system's stable external identifier.
  5. Process the response and retry only when it is safe to do so.
  6. Reconcile the two systems periodically to find missed or conflicting updates.

Do not identify an order using mutable information such as a customer name or order total. Use a stable source identifier and preserve the Endless identifier returned by the API.

Make retries safe

Network failures can happen after Endless has accepted a request but before the source receives the response. Before retrying a create operation, check whether the order has already been created. A retry must not create a duplicate order or repeat a non-repeatable status change.

Keep a durable record of the source identifier, Endless identifier, last successful update, and last error. Use incremental synchronization and periodic reconciliation rather than repeatedly loading the entire order history.

Optional on-demand order import

The integration can store an Import Order Webhook URL. When an Endless user requests an on-demand order import and supplies an external order ID, Endless sends a request to that URL. Your service is responsible for retrieving the order from its source and writing it to Endless through the GraphQL API.

Treat the webhook as a request to begin work, not proof that an order was imported. Validate requests, return promptly, process retry-safe work, and record the final result in your integration logs.

Handle errors and responses

GraphQL responses can contain data, errors, or both. Always inspect errors before marking an order as synchronized. Validate status and enum mappings against the API reference, and do not silently discard fields that the source could not translate.

Log enough information to identify the integration, source order, Endless order, operation, request time, and sanitized response. Never log the access token, API key, API secret, or sensitive customer information unnecessarily.

Protect and rotate credentials

Store credentials in a secrets vault or password manager and use them only from a trusted server or data platform. Never place them in browser code, source control, logs, or support messages.

To rotate credentials, open the integration in Endless and select Regenerate credentials. The previous credentials stop working immediately, so deploy the new access token to the connected system as part of the same change.

Troubleshooting

ProblemWhat to check
The request is unauthorizedConfirm that X-EC-Access-Token contains the access token with no Bearer prefix and that the credentials have not been regenerated.
The connection test works but an order operation failsCompare the operation and variables with the current API reference and confirm referenced products and configuration exist.
The order is created as a local order or has the wrong sourceConfirm that sourceIntegrationId contains the Custom Sales integration record ID.
The sales channel is rejectedConfirm that salesChannelId is present and references an existing sales channel in the same company.
Duplicate orders appearUse a stable external order identifier and check for an existing order before retrying creation.
A Sales Order field changes unexpectedlyCheck whether the same field was updated by the source integration after it was edited in Endless.
Statuses do not matchReview the status mapping and only send transitions supported by the current API.
The on-demand import does nothingConfirm the Import Order Webhook URL, inspect your service logs, and verify that the service wrote the order through GraphQL.

Getting help

Endless Support can help with access, credentials, company scope, order-source behavior, and behavior that does not match the current API reference. Designing mappings, synchronization logic, reconciliation, or a production connector is the responsibility of your technical team or implementation partner.

When reporting an API problem, include the integration name, source order identifier, request time and time zone, GraphQL operation name, sanitized query and variables, company handle, and the error response. Never include credentials.