Create an inventory feed workflow

Create the workflow that receives the rooftop's inventory feed from a partner.

POSThttps://api.spyne.ai/partner/input-workflow
AuthBearer token (console user)Rate limitNot documentedProcessingSynchronous save; partner onboarding and the inventory pull run in the background.

The server validates the body, looks up the dealer group's owner user and the rooftop's reseller status, and applies partner flags (CGI-only partners get the CGI flow; some partners get image ids in output links). It then saves the workflow and its rules and clears the feed cache for the rooftop. After the save it opens a partner onboarding request with the partner name and any contact fields sent. If any of productOptions.spin, catalog or featureVideo is true, it also starts an inventory pull from the partner in the background. Only one non-reseller workflow can exist per partnerId + dealerId.

Before you call it

  • You need the bearer token of a signed-in console user. The route does not check that the rooftop belongs to the caller.
  • Get partnerId from List inventory and history partners with category=IMS, and the rooftop's dealer id at that partner.
  • Check List inventory feed workflows first. If a workflow for the same partnerId + dealerId exists, update it instead.
  • partnerId and dealerId are required. A partner that is not in the list cannot be saved through this endpoint.
  • The save is synchronous. The partner onboarding request and the inventory pull run in the background; their failures are not reported. Rate limit: not documented.

Request body

Requiredalways sendOptionalcan be left out
ParameterTypeRequiredDescription
Header———
AuthorizationstringRequiredBearer YOUR_TOKEN
Body———
namestringRequiredWorkflow name. The UI sends <partner name> - Inventory Provider.
partnerIdstringRequiredPartner id from the partner list. Must be a valid id of an existing partner.
dealerIdstringRequiredThe rooftop's id at the partner.
teamIdstringRequired<teamId> of the rooftop.
enterpriseIdstringOptional<enterpriseId>. Optional in validation, but send it. When sent, the dealer group's owner user must be found or the request fails with 400.
partnerProviderTypesstring[]OptionalAny of IMS, PHOTO, CGI. Default empty. Send ["IMS"] for the inventory feed.
isActivebooleanOptionalDefault true.
createDraftbooleanOptionalDefault false. The UI sends true.
thresholdCountsobjectOptionalnewCars and usedCars, numbers. 0 is rejected; use -1 to disable.
preliminaryConfigsobjectOptionalenabled (boolean) and thresholds with new and used (numbers).
productOptionsobjectOptionalspin, catalog, featureVideo (validated as booleans), mediaKit, conversationalAi.
processingConfigsobjectOptionalbackgroundId (number), numberplateId, bannerId, videoId, voiceId, musicId (strings), aiHotspot (boolean).
rulesarrayOptionalEach rule needs processingConfigs (object).
rules[].conditionsarrayOptionalEach condition needs column_name, condition (equals, contains, starts_with, ends_with) and value.
customIntegrationobjectOptionalPartner add-on selector, for example { "evox": { "condition": "new" } }. Converted into customIntegrations.
poc_name, poc_email, poc_contactstringOptionalPassed to the partner onboarding request. Not stored on the workflow.

Fields not in the workflow schema (for example partnerName, logo, approved) are not stored.

Request checklist
  1. Authenticate: set Authorization: Bearer YOUR_TOKEN.
  2. Identify the feed: send name, partnerId, dealerId, teamId and enterpriseId.
  3. Mark it as inventory: send partnerProviderTypes: ["IMS"].
  4. Thresholds: send -1 (disabled) or a positive number, never 0.
  5. Finish: on success, mark the checklist task IMS Integration done.

Sample request

curl -X POST "https://api.spyne.ai/partner/input-workflow" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Example Inventory Feed - Inventory Provider",
    "partnerId": "<partnerId>",
    "dealerId": "<dealerId>",
    "enterpriseId": "<enterpriseId>",
    "teamId": "<teamId>",
    "isActive": true,
    "createDraft": true,
    "partnerProviderTypes": ["IMS"],
    "thresholdCounts": { "newCars": -1, "usedCars": -1 },
    "preliminaryConfigs": { "enabled": false, "thresholds": { "new": -1, "used": -1 } }
  }'
import requests

res = requests.post(
    "https://api.spyne.ai/partner/input-workflow",
    headers={"Authorization": "Bearer YOUR_TOKEN"},
    json={
        "name": "Example Inventory Feed - Inventory Provider",
        "partnerId": "<partnerId>",
        "dealerId": "<dealerId>",
        "enterpriseId": "<enterpriseId>",
        "teamId": "<teamId>",
        "partnerProviderTypes": ["IMS"],
        "thresholdCounts": {"newCars": -1, "usedCars": -1},
    },
)
if res.status_code == 409:
    pass  # a workflow already exists for this partnerId + dealerId; update it instead
workflow = res.json().get("data")
const res = await fetch("https://api.spyne.ai/partner/input-workflow", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Example Inventory Feed - Inventory Provider",
    partnerId: "<partnerId>",
    dealerId: "<dealerId>",
    enterpriseId: "<enterpriseId>",
    teamId: "<teamId>",
    partnerProviderTypes: ["IMS"],
    thresholdCounts: { newCars: -1, usedCars: -1 },
  }),
});
const body = await res.json();

Sample response

{
  "success": true,
  "message": "Input workflow created successfully",
  "data": {
    "_id": "<workflowId>",
    "name": "Example Inventory Feed - Inventory Provider",
    "enterpriseId": "<enterpriseId>",
    "teamId": "<teamId>",
    "userId": "<userId>",
    "partnerId": "<partnerId>",
    "dealerId": "<dealerId>",
    "isActive": true,
    "createDraft": true,
    "reseller": false,
    "partnerProviderTypes": ["IMS"],
    "thresholdCounts": { "newCars": -1, "usedCars": -1 },
    "rules": [],
    "latestFileUpload": null,
    "createdAt": "2026-01-01T00:00:00.000Z",
    "updatedAt": "2026-01-01T00:00:00.000Z"
  }
}
{ "success": false, "message": "Validation failed", "errors": ["Partner ID is required", "Dealer ID is required"] }
{ "success": false, "message": "Failed to create input workflow", "error": "Failed to fetch userId for the provided enterpriseId" }
{ "success": false, "error": "Invalid Authentication" }
{
  "success": false,
  "message": "Failed to create input workflow",
  "error": "Input workflow with the same partnerId and dealerId already exists",
  "isPresent": true
}
{ "success": false, "message": "Failed to create input workflow", "error": "<error message>" }

Response parameters

ParameterTypeDescription
successbooleantrue on 201.
messagestringResult message.
dataobjectThe created workflow with rules and latestFileUpload. Same fields as List inventory feed workflows.
isPresentbooleanOn 409 only. A workflow for this partnerId + dealerId already exists.

Errors

StatusCodeWhen it happens
400Validation failedMissing name, partnerId, dealerId or teamId; invalid or unknown partnerId; a threshold is 0 or not a number; bad productOptions; bad rules or conditions.
400Failed to fetch userId for the provided enterpriseIdenterpriseId was sent and the owner user could not be found or looked up.
401Authentication token required or Invalid AuthenticationMissing or rejected token.
409isPresent: trueA non-reseller workflow with the same partnerId + dealerId exists.
500Failed to create input workflowDatabase or other error. If saving rules fails, the workflow itself may already be saved.

What happens next

Store the returned _id and use Update an inventory feed workflow for later edits. On 409, find the existing workflow with List inventory feed workflows (partnerId + dealerId) and update it. After a successful IMS save, the UI calls Mark a checklist task done in the Checklist section with taskName: "IMS Integration".


Did this page help you?