Custom Inbound
Custom Inbound API
The Custom Inbound API provides a generic REST endpoint for pushing data into Avvyr from any external system. It's designed for scenarios where you need to sync inventory, orders, products, prices, or customers from a system that doesn't have a pre-built connector.
How it works
- Create a custom integration in the Avvyr dashboard or via the Management API — an API key is generated automatically
- Send data to the inbound endpoint with the API key and an action identifier
- The platform validates and enqueues the request, returning a
202 Acceptedwith a message ID - A background worker picks up the message, routes it by action type, and processes it against the Avvyr Backend API
External System → POST /integrations/custom/inbound → Service Bus Queue → Worker → Avvyr
Authentication
Custom inbound requests are authenticated with an API key in the Authorization header:
Authorization: Bearer <api-key>
The API key is generated when the custom integration is created. It is stored securely in Azure Key Vault, and a SHA-256 hash is kept on the Integration document for fast lookup. You can regenerate the key at any time via the Management API.
Request format
POST /integrations/custom/inbound
Authorization: Bearer <api-key>
Content-Type: application/json
{
"action": "inventory.set",
"entityId": "SKU-12345",
"data": {
// Action-specific payload — see actions below
}
}
| Field | Type | Description |
|---|---|---|
action | string | Required. The action to perform — see supported actions below |
entityId | string | Optional identifier for the entity being operated on |
data | object | Required. The action-specific payload |
Response
HTTP 202 Accepted
{
"messageId": "abc123-def456-..."
}
The messageId can be used to track the event in the integration dashboard.
Supported actions
inventory.set
Set absolute inventory levels for one or more SKUs.
{
"action": "inventory.set",
"data": {
"items": [
{ "sku": "CHAIR-UNO-BLK", "quantity": 42, "warehouseId": "wh-01" },
{ "sku": "SOFA-VEL-GRY", "quantity": 8, "warehouseId": "wh-01" }
]
}
}
inventory.adjust
Adjust inventory levels relative to current stock (increment or decrement).
{
"action": "inventory.adjust",
"data": {
"items": [{ "sku": "CHAIR-UNO-BLK", "adjustment": -2, "reason": "Damaged stock" }]
}
}
order.create
Create a new order in Avvyr.
{
"action": "order.create",
"data": {
"externalId": "ERP-ORDER-789",
"customer": {
"email": "customer@example.com",
"firstName": "Anna",
"lastName": "Svensson"
},
"lineItems": [{ "sku": "CHAIR-UNO-BLK", "quantity": 1, "unitPrice": 4990 }]
}
}
order.update
Update an existing order (e.g. status changes, tracking info).
{
"action": "order.update",
"entityId": "order-id-from-avvyr",
"data": {
"status": "shipped",
"trackingNumber": "PKG-123456789"
}
}
product.upsert
Create or update products in bulk.
{
"action": "product.upsert",
"data": {
"products": [
{
"sku": "CHAIR-UNO-BLK",
"name": "Lounge Chair Uno — Black",
"sellingPrice": 4990,
"description": "Minimalist lounge chair in black leather."
}
]
}
}
price.set
Set prices for one or more SKUs.
{
"action": "price.set",
"data": {
"items": [{ "sku": "CHAIR-UNO-BLK", "sellingPrice": 4990, "costPrice": 2200 }]
}
}
customer.upsert
Create or update customers.
{
"action": "customer.upsert",
"data": {
"email": "customer@example.com",
"firstName": "Anna",
"lastName": "Svensson",
"phone": "+46701234567"
}
}
Setting up a custom integration
Via Management API
# 1. Create the integration
POST /v1/integrations/
Authorization: Bearer <management-token>
Content-Type: application/json
{
"service": "custom",
"enabled": true,
"name": "My ERP Sync"
}
# Response includes the API key — store it securely
# {
# "id": "integration-id",
# "apiKey": "avvyr_int_live_xxxxx..."
# }
Regenerating the API key
POST /v1/integrations/{integrationId}/regenerate-key
Authorization: Bearer <management-token>
Error handling
If the inbound request fails validation (invalid action, missing fields), the API returns a 400 Bad Request with details. If the request is accepted but the worker fails to process it, the event appears as failed in the integration dashboard with full error details. You can retry it manually or let the automatic retry mechanism handle it.
Tracking events
Every inbound request creates an IntegrationEvent that you can track via the Management API:
# Filter events for a specific integration
POST /v1/integrations/events/filter
Authorization: Bearer <management-token>
Content-Type: application/json
{
"integrationId": "integration-id",
"status": "failed"
}