@deliverart/sdk-js-integration
Integration management package for the DeliverArt JavaScript SDK.
Tilby integration reads and updates expose syncSettings.respectDeliverartChannel
(default true) and syncSettings.removeProductsWithoutDeliverartChannel
(default false). Saving changes affects later webhooks and the next full sync;
it never starts a full synchronization. Product mappings expose the nullable
deliverartChannelAssigned observation, independently of local sales channels.
Installation
npm install @deliverart/sdk-js-integration @deliverart/sdk-js-core
Exported Types
Core Types
Integration- Integration configurationActivatableIntegration- Integration that can be activated/deactivatedIntegrationActivationRequest- Request to activate an integrationIntegrationCancellationRequest- Request to cancel an integration
Integration Types
Integration types vary by service (delivery partners, payment gateways, etc.)
The ecommerce info payload exposes the cached menu DTO. Item entries include
compositions, the ids of removable base ingredients/components to send as
writable order item removals.
Public ecommerce menu items also expose images with the existing Image contract
and generated variants. Missing images in legacy responses default to an empty
list. showProductImages defaults to true on public info and integration reads;
it is writable through UpdateIntegrationEcommerce. An explicit false hides
product photos in editorial and grid layouts; compact menus remain text-only.
PATCH validation does not inject appearance defaults into unrelated updates.
It also exposes the POS currency on both the top-level ecommerce info payload
and pointOfSale, so storefronts can format menu prices, totals, payment
summaries, and order history without assuming EUR.
IRI Types
IntegrationIri- Integration IRI (/integrations/:id)ActivationRequestIri- Activation request IRICancellationRequestIri- Cancellation request IRI
Available Requests
GetIntegrations
Get list of available integrations.
import { GetIntegrations } from '@deliverart/sdk-js-integration'
const integrations = await sdk.call(
new GetIntegrations({
query: {
company: '/companies/123',
type: 'DELIVERY',
},
}),
)
GetIntegrationDetails
Get detailed information about an integration.
import { GetIntegrationDetails } from '@deliverart/sdk-js-integration'
const integration = await sdk.call(new GetIntegrationDetails('integration-123'))
Integration Operational Issues
Integration issues expose a provider-neutral workflow for operational anomalies. Issues include their flow scope, severity, status, remote resource key, consecutive failure count, operator acknowledgement, resolution, and last successful execution.
import {
AcknowledgeIntegrationIssue,
GetAdminIntegrationIssues,
ResolveIntegrationIssue,
} from '@deliverart/sdk-js-integration'
const issues = await sdk.call(
new GetAdminIntegrationIssues({
query: {
service: ['deliveroo', 'glovo'],
status: 'attention_required',
severity: ['error', 'critical'],
'resolvedAt[exists]': false,
page: 1,
},
}),
)
await sdk.call(new AcknowledgeIntegrationIssue('integration-id', 'issue-id'))
await sdk.call(new ResolveIntegrationIssue('integration-id', 'issue-id'))
Both workflow actions send an empty application/merge-patch+json request. The paginated
/integration_issues collection is reserved for integration administrators; the existing
/integrations/{id}/issues collection remains available for integration-scoped views.
Kitchen Session Handoff
Create a short-lived, single-use handoff code for a Kitchen integration, then exchange it for the existing Kitchen access-token details. This lets an authorized Hub session open KDS without placing a persistent Kitchen token in a browser URL.
import {
CreateIntegrationKitchenSessionHandoff,
ExchangeIntegrationKitchenSessionHandoff,
} from '@deliverart/sdk-js-integration'
const handoff = await hubSdk.call(
new CreateIntegrationKitchenSessionHandoff('kitchen-integration-id'),
)
const kitchenAccessToken = await kdsSdk.call(
new ExchangeIntegrationKitchenSessionHandoff({ code: handoff.code }),
)
ActivateIntegration
Request activation of an integration.
import { ActivateIntegration } from '@deliverart/sdk-js-integration'
const activation = await sdk.call(
new ActivateIntegration({
integration: '/integrations/123',
pointOfSale: '/point_of_sales/456',
config: {
apiKey: 'your-api-key',
// ... integration-specific config
},
}),
)
CancelIntegration
Request cancellation of an active integration.
import { CancelIntegration } from '@deliverart/sdk-js-integration'
const cancellation = await sdk.call(
new CancelIntegration({
integration: '/integrations/123',
reason: 'No longer needed',
}),
)
Deliveroo Manual Portal Activation
Deliveroo integrations expose manualActivationCompleted and manualActivationCompletedAt so operator tools can track whether the final manual activation step has been completed in the Deliveroo portal.
import {
GetIntegrationDeliverooList,
UpdateIntegrationDeliveroo,
} from '@deliverart/sdk-js-integration'
const pending = await sdk.call(
new GetIntegrationDeliverooList({
query: {
manualActivationCompleted: false,
},
}),
)
await sdk.call(
new UpdateIntegrationDeliveroo('deliveroo-integration-id', {
manualActivationCompleted: true,
}),
)
CassaInCloud Catalog Channel Policies
CassaInCloud exposes separate remote channel policies:
inboundProductChannelsfilters the Cassa categories and products imported into Deliverart.outboundProductChannelsis captured and applied when Deliverart creates remote Cassa categories and products.productChannelsis a deprecated alias forinboundProductChannelsand remains available for one compatibility release only.
Audits and explicit channel reconciliation run asynchronously through the nested API Platform
catalog_mapping_processes resource. The process preserves its operation, scopes, target
channel snapshot, counters, and typed issues.
import {
CreateIntegrationCassaInCloudCatalogMappingProcess,
GetIntegrationCassaInCloudCatalogMappingProcessIssues,
GetIntegrationCassaInCloudCatalogMappingProcessDetails,
GetIntegrationCassaInCloudCatalogMappingProcesses,
RetryIntegrationCassaInCloudCatalogMappingProcess,
} from '@deliverart/sdk-js-integration'
const process = await sdk.call(
new CreateIntegrationCassaInCloudCatalogMappingProcess('integration-id', {
operation: 'reconcile_channels',
scopes: ['categories', 'products'],
}),
)
const details = await sdk.call(
new GetIntegrationCassaInCloudCatalogMappingProcessDetails('integration-id', process.id),
)
const history = await sdk.call(
new GetIntegrationCassaInCloudCatalogMappingProcesses('integration-id', {
query: { operation: 'audit', 'order[createdAt]': 'desc' },
}),
)
const issues = await sdk.call(
new GetIntegrationCassaInCloudCatalogMappingProcessIssues('integration-id', process.id, {
query: { retryable: true },
}),
)
const retry = await sdk.call(
new RetryIntegrationCassaInCloudCatalogMappingProcess('integration-id', process.id),
)
Elephant Integrations
Elephant uses one integration per point of sale and one or more nested Restaurant
memberships. Create the integration first, then provision each Restaurant with its
Deliverart optional sales mode, required fallback category, catalog channels, order
type, preparation time, and acceptance timeout. Set salesMode to null to use base
catalog prices.
The activation-request and lead contracts accept service: 'elephant' with the same
integrationElephantDataSchema payload. This includes create, detail, update/response,
lead conversion, and all response schemas used by HUB and Admin.
import {
CreateIntegrationElephantRestaurantMapping,
CreateIntegrationElephant,
CreateIntegrationElephantRestaurant,
GetIntegrationElephantCatalogImportProcessDetails,
GetIntegrationElephantCatalogImportProcesses,
GetIntegrationElephantOrderReleases,
GetIntegrationElephantRestaurantCatalogProducts,
GetIntegrationElephantRestaurantMappings,
GetIntegrationElephantRestaurants,
GetIntegrationRequestLogs,
RefreshIntegrationElephantRestaurantCatalog,
RetryIntegrationElephantProvisioning,
StartIntegrationElephantCatalogImport,
UpdateIntegrationElephant,
UpdateIntegrationElephantRestaurant,
} from '@deliverart/sdk-js-integration'
const integration = await sdk.call(
new CreateIntegrationElephant({
pointOfSale: '/point_of_sales/8a745a0b-a68b-4f98-87ca-74df04a3bfe3',
credentialMode: 'managed',
}),
)
const restaurant = await sdk.call(
new CreateIntegrationElephantRestaurant(integration.id, {
name: 'Restaurant Centre',
platform: 'migros_yemek',
platformRestaurantId: 'restaurant-123',
platformChainId: 'group-456',
authentication: {
secret_key: '12345678901234567890123456789012',
x_api_key: 'write-only-platform-key',
store_id: 'restaurant-123',
store_group_id: 'group-456',
},
salesMode: null,
category: '/menu_item_categories/20c71a6a-c924-42e0-9078-e3f672704dbb',
defaultTaxRate: 10,
channels: ['application', 'elephant'],
orderType: 'delivery',
defaultPreparationTime: 15,
acceptanceTimeout: 5,
}),
)
await sdk.call(
new UpdateIntegrationElephant(integration.id, {
defaultRestaurantMembership: `/integrations/elephant/${integration.id}/restaurants/${restaurant.id}`,
}),
)
await sdk.call(
new UpdateIntegrationElephantRestaurant(integration.id, restaurant.id, {
acceptanceTimeout: 10,
}),
)
const staleRestaurants = await sdk.call(
new GetIntegrationElephantRestaurants(integration.id, {
query: {
catalogStatus: 'stale',
status: ['active', 'paused'],
'order[name]': 'asc',
},
}),
)
await sdk.call(new RetryIntegrationElephantProvisioning(integration.id))
await sdk.call(new RefreshIntegrationElephantRestaurantCatalog(integration.id, restaurant.id))
const catalogImport = await sdk.call(
new StartIntegrationElephantCatalogImport(integration.id, restaurant.id),
)
const catalogImportDetails = await sdk.call(
new GetIntegrationElephantCatalogImportProcessDetails(
integration.id,
restaurant.id,
catalogImport.id,
),
)
const platformProducts = await sdk.call(
new GetIntegrationElephantRestaurantCatalogProducts(integration.id, restaurant.id, {
query: { q: 'pizza', page: 1 },
}),
)
const mappings = await sdk.call(
new GetIntegrationElephantRestaurantMappings(integration.id, restaurant.id, {
query: { role: 'product', page: 1 },
}),
)
await sdk.call(
new CreateIntegrationElephantRestaurantMapping(integration.id, restaurant.id, {
role: 'product',
platformReference: platformProducts.data[0].platformReference!,
platformGroupReference: null,
appMenuItemId: 'deliverart-menu-item-id',
appModifierId: null,
appVariantId: null,
appSalesModeId: null,
}),
)
const releases = await sdk.call(
new GetIntegrationElephantOrderReleases(integration.id, {
query: { status: ['preparing', 'failed'], page: 1 },
}),
)
const requestLogs = await sdk.call(
new GetIntegrationRequestLogs(integration.id, {
query: { outcome: 'server_error', page: 1 },
}),
)
Use credentialMode: 'provided' only when attaching an existing Elephant Tenant and
App; tenantId, appId, and personalAccessToken are then all required. Restaurant
authentication is write-only. Deleting a Restaurant membership starts its asynchronous
removing lifecycle; the Elephant integration itself does not expose a direct DELETE
operation.
The following request classes cover the current API surface:
GetIntegrationElephantList,GetIntegrationElephantDetailsCreateIntegrationElephant,UpdateIntegrationElephantGetIntegrationElephantRestaurants,GetIntegrationElephantRestaurantDetailsCreateIntegrationElephantRestaurant,UpdateIntegrationElephantRestaurantDeleteIntegrationElephantRestaurantRetryIntegrationElephantProvisioning,TestIntegrationElephantConnection,ReconcileIntegrationElephantRetryIntegrationElephantRestaurantProvisioning,TestIntegrationElephantRestaurantConnection,RefreshIntegrationElephantRestaurantCatalog,PauseIntegrationElephantRestaurant,ResumeIntegrationElephantRestaurantGetIntegrationElephantRestaurantCatalogProducts,GetIntegrationElephantRestaurantCatalogOptions,GetIntegrationElephantRestaurantCatalogVariants,GetIntegrationElephantRestaurantAppCatalogMirrorGetIntegrationElephantRestaurantMappings,CreateIntegrationElephantRestaurantMapping,DeleteIntegrationElephantRestaurantMappingGetIntegrationElephantCatalogImportProcesses,StartIntegrationElephantCatalogImport,GetIntegrationElephantCatalogImportProcessDetailsGetIntegrationElephantOrderReleases,GetIntegrationElephantOrderReleaseDetailsGetIntegrationRequestLogs,GetIntegrationRequestLogDetails
Restaurant, catalog, mapping, order-release, and request-log collections are paginated. Catalog-import history is intentionally unpaginated and supports status, step, date, and ordering filters; only one pending or running import is allowed per Restaurant membership. Use their exported query types rather than constructing query strings manually. Request logs are the API's sanitized diagnostics model: tokens and payload bodies are deliberately absent.
Complete Usage Example
import { sdk } from './lib/sdk'
import {
GetIntegrations,
ActivateIntegration,
CancelIntegration,
} from '@deliverart/sdk-js-integration'
async function integrationManagement() {
// Get available delivery integrations
const integrations = await sdk.call(
new GetIntegrations({
query: {
type: 'DELIVERY',
company: '/companies/123',
},
}),
)
// Activate delivery partner
const activation = await sdk.call(
new ActivateIntegration({
integration: integrations.data[0]['@id'],
pointOfSale: '/point_of_sales/456',
config: {
apiKey: process.env.DELIVERY_API_KEY,
webhookUrl: 'https://myapp.com/webhooks/delivery',
},
}),
)
// Cancel integration
await sdk.call(
new CancelIntegration({
integration: activation.integration,
reason: 'Switching to different provider',
}),
)
}
License
MIT
CassaInCloud order lifecycle decisions
Webhook schemas expose optional nullable orderLifecycleOutcome and
orderLifecycleRevision. amendment_review_required means the callback was
recorded without changing the amended order; review its current state in Hub.
Receipt of READY is not proof of applied preparation. Historical null/absent
outcomes carry no application evidence. Deploy API migration
Version20260918060000 before using the updated worker and client contract.
Tilby amended-order remote deletion
MappingSyncFailureCode.AMENDED_ORDER_REMOTE_DELETED serializes as
amended_order_remote_deleted. It accompanies manual resolution after confirmed
remote deletion of an order protected by amendment history or a neighbor intent.
The canonical order and payment history are retained. Clients must describe
register review separately from correction completion or confirmed refund.
Ecommerce appearance
theme supports primary, accent, background, surface, text, and
muted hex colors. fontFamily and headingFontFamily select from inter,
poppins, nunito_sans, and playfair_display. Existing integrations may
omit the new keys; public info resolves defaults to preserve existing branding.
These settings also travel through lead/activation data. Font URLs and arbitrary
font names are not supported. The existing 2.37 theme passthrough preserves the
additive keys for consumers during a coordinated rollout.
Ecommerce payment configuration references
paymentConfigs uses method-specific references such as /payment_configs/credit_card/<uuid>. The method is a literal route segment; only the configuration identifier is a UUID. The SDK accepts Cash, Credit Card, Bank Transfer, Stripe and Ticket references, including SDK objects serialized by settings forms, and rejects unsupported methods or malformed identifiers. POS integration collections and ecommerce settings use the same validated contract.
Kitchen customer visibility
Kitchen integrations expose showCustomerInfo and showCustomerAddress.
Both default to false on creation and when parsing older API responses.
Enable customer information before enabling the address. To hide all customer
details, update both settings together:
await client.call(new UpdateIntegrationKitchen(integrationId, {
showCustomerInfo: false,
showCustomerAddress: false,
}))
Omitted PATCH settings are preserved. These are KDS display preferences and do not redact order API responses. Reload KDS after changing them.
Cassa in Cloud full-import modifier reconciliation
The existing full inbound menu sync finishes with reconcile_modifiers. Sync
processes expose an optional modifierReconciliation summary containing status,
processed, reconciled, and blocked. Older responses omit this field. The
active workflow place is reconciling_modifiers, and review findings use the
existing menu error-log resource with step=reconcile_modifiers.
Only a successful full import can establish complete, unique correspondences between equivalent duplicate groups/choices on the same mapped product. This preserves catalog UUIDs, historical order contents, and native provider mappings. It does not retry blocked orders; use explicit order-delivery recovery separately.
CassaInCloud apiKey and Tilby apiToken are write-only inputs. Their read
models strip historical secret fields and expose optional apiKeyConfigured /
apiTokenConfigured presence metadata. Missing metadata is unknown during the
frontend-first API rollout; it must not be inferred by retaining a returned
secret. Complete/create writes still require a credential; PATCH may omit it to
preserve the server-owned value and rejects explicit blanks. Cassa list queries
no longer accept an API key. This is a breaking read-model change: update and
pin all clients before releasing the backend's write-only contract.
CassaInCloud/Tilby create, update and activation credentials are limited to
32,768 UTF-8 bytes, matching authenticated native storage. Their shared
providerCredentialSchema retains existing input trimming/required diagnostics;
byte counting accepts all approved multi-byte source token lengths without
truncation. Private migration installation preserves captured bytes directly
through the native cipher, independently of human-entered SDK input cleanup.