HTTP API
Call the Container API directly over HTTP from any language.
The Container API is a standard REST API at http://cde-container-api (port 80). No authentication is needed — it's only accessible from inside the container environment. You can call it from any language using HTTP requests.
Each example below shows the PHP SDK equivalent alongside the raw HTTP request, so you can see what happens under the hood.
Write products to output
Used by data source connectors to import product data into the platform.
PHP SDK:
$this->containerApi->appendManyToOutputFile([
['id' => '1', 'name' => 'Product A', 'price' => '9.99'],
['id' => '2', 'name' => 'Product B', 'price' => '19.99'],
]);HTTP:
curl -X POST http://cde-container-api/output/output \
-H "Content-Type: application/json" \
-d '{
"data": [
{"id": "1", "name": "Product A", "price": "9.99"},
{"id": "2", "name": "Product B", "price": "19.99"}
]
}'Response (201):
{
"message": "Written successfully."
}The data field is an array of flat key-value objects. Each object represents one product. The optional meta.separator field controls how nested keys are flattened (default: -).
Endpoint reference: Write to output file
Read products from input
Used by export connectors to read all processed product data from the platform.
Read one product at a time
PHP SDK:
foreach ($this->containerApi->yieldFromInputFile() as $product) {
// process $product
}HTTP:
# Read the next product
curl http://cde-container-api/input/input/nextResponse (200):
{
"message": "",
"data": {
"id": "1",
"name": "Product A",
"price": "9.99"
}
}Each call returns one product and advances the cursor. When there are no more products, data is empty. Call /input/input/restart to reset the cursor.
Endpoint reference: Read input file
Read products in batches
PHP SDK:
foreach ($this->containerApi->yieldBatchFromInputFile(100) as $batch) {
// process $batch (array of up to 100 products)
}HTTP:
# Read a batch of 100 products
curl "http://cde-container-api/input/input/next_batch?size=100"Response (200):
{
"message": "",
"data": [
{"id": "1", "name": "Product A", "price": "9.99"},
{"id": "2", "name": "Product B", "price": "19.99"}
]
}Batch size must be between 1 and 999.
Endpoint reference: Read input file batch
Count items
PHP SDK:
$total = $this->containerApi->countItemsFromInputFile();HTTP:
curl http://cde-container-api/items/input/countResponse (200):
{
"message": "",
"data": 1500
}Endpoint reference: Items count
Read delta input
Used by export-delta connectors. Instead of a single input type, use new, modified, unchanged, or deleted.
PHP SDK:
foreach ($this->containerApi->yieldFromNewFile() as $product) { }
foreach ($this->containerApi->yieldFromModifiedFile() as $product) { }
foreach ($this->containerApi->yieldFromDeletedFile() as $product) { }HTTP:
curl "http://cde-container-api/input/new/next_batch?size=100"
curl "http://cde-container-api/input/modified/next_batch?size=100"
curl "http://cde-container-api/input/deleted/next_batch?size=100"The response format is the same as regular input. Replace input in the URL with the delta type.
Stream API
Used by stream connectors — connectors that exchange data with the platform through the Stream API rather than as batch files. Instead of reading and writing whole files, they read items from an input stream and write items to an output stream, one batch at a time, tracking their position with offsets so each run picks up where the previous one left off. The Container API proxies these calls to the Stream API and handles authentication, rate limiting, and retries for you. Stream ids are resolved server-side from the run context, so you address the endpoints simply as input-stream and output-stream.
The typical loop is: read a batch of items → process them → write results to the output stream → commit the offsets you handled. Repeat until the input reports complete.
Read items from the input stream
Items are returned as newline-delimited JSON (application/x-ndjson) — one record per line. Each line is one of: item (a data record), complete (no more items), incomplete (the server reached its time budget — call again to continue), or error.
curl http://cde-container-api/stream-api/input-stream/items \
-H "Accept: application/x-ndjson"Response (200, application/x-ndjson):
{"item":{"partition":0,"offset":42,"payload":"{\"id\":\"1\",\"name\":\"Product A\"}","headers":{}}}
{"item":{"partition":0,"offset":43,"payload":"{\"id\":\"2\",\"name\":\"Product B\"}","headers":{}}}
{"complete":{"reason":"eof_reached"}}Read line by line and act on the frame type. On incomplete, issue the same request again to resume from where you left off.
Endpoint reference: Read input-stream items
Read and commit input-stream offsets
Offsets track how far your connector has consumed each partition. Read the last committed offsets:
curl http://cde-container-api/stream-api/input-stream/offsets \
-H "Accept: application/vnd.api+json"Response (200):
{
"data": {
"type": "consumer-offsets",
"id": "<consumer-id>",
"attributes": { "offsets": [ { "partition": 0, "offset": 43 } ] }
}
}Commit the offsets you have finished processing so a restart resumes past them (at-least-once). Send the offset of the next record to read:
curl -X PATCH http://cde-container-api/stream-api/input-stream/offsets \
-H "Content-Type: application/vnd.api+json" \
-d '{"data":{"type":"consumer-offsets","attributes":{"offsets":[{"partition":0,"offset":44}]}}}'Commit after you have written the corresponding output (send-then-commit) — that way a failure only ever redelivers the in-flight batch instead of dropping it.
Endpoint reference: Read offsets · Commit offsets
Write items to the output stream
Send items as newline-delimited JSON — one item per line. The HTTP method selects the write mode:
| Method | Mode |
|---|---|
POST | Create items |
PUT | Replace items |
PATCH | Update items |
DELETE | Delete items |
curl -X POST http://cde-container-api/stream-api/output-stream/items \
-H "Content-Type: application/x-ndjson" \
--data-binary $'{"id":"1","name":"Product A","price":"9.99"}\n{"id":"2","name":"Product B","price":"19.99"}\n'Response (200):
{ "message": "Items written to output stream." }Delete all items from the output stream
To clear the output stream before a full rewrite, delete with all=true:
curl -X DELETE "http://cde-container-api/stream-api/output-stream/items?all=true" \
-H "Accept: application/vnd.api+json"Write feedback
Used by export and export-delta connectors to report the result of each product export back to the platform.
PHP SDK:
$this->containerApi->appendToFeedbackFile([
'id' => $product['id'],
'status' => 'success',
]);
// Or in bulk
$this->containerApi->appendManyToFeedbackFile([
['id' => '1', 'status' => 'success'],
['id' => '2', 'status' => 'error', 'message' => 'Invalid SKU'],
]);HTTP:
curl -X POST http://cde-container-api/output/feedback \
-H "Content-Type: application/json" \
-d '{
"data": [
{"id": "1", "status": "success"},
{"id": "2", "status": "error", "message": "Invalid SKU"}
]
}'Response (201):
{
"message": "Written successfully."
}Feedback is imported as an additional data source on the next site run, so end-users can see which products succeeded or failed.
Endpoint reference: Write to output file (feedback uses the same endpoint with type feedback)
Log messages
Log messages appear in the Dev Portal monitoring.
PHP SDK:
$this->containerApi->info('Import started.');
$this->containerApi->warning('Skipped 3 products with missing IDs.');
$this->containerApi->error('API returned 503, retrying...');HTTP:
# Log levels: debug, info, notice, warning, error, critical, alert, emergency
curl -X POST http://cde-container-api/activity/logs/info \
-H "Content-Type: application/json" \
-d '{
"message": "Import started.",
"context": {}
}'Response (201):
{
"message": "success"
}The context field is optional — use it to attach structured data to the log entry.
Endpoint reference: Add log
Send notifications
Notifications appear in the end-user's notification panel on the ProductsUp platform.
PHP SDK:
$this->containerApi->sendNotification('info', 'Export completed successfully.');HTTP:
# Notification levels: info, notice, warning, error, success
curl -X POST http://cde-container-api/activity/notifications/info \
-H "Content-Type: application/json" \
-d '{
"message": "Export completed successfully.",
"context": {}
}'Response (201):
{
"message": "success"
}Endpoint reference: Add notification
Health check
Verify the Container API is running and ready.
curl http://cde-container-api/pingResponse (200):
{
"message": "pong"
}Endpoint reference: Ping
Error responses
All error responses follow the same format:
{
"message": "Validation failed",
"errors": {
"field_name": "Error description"
}
}| Status | Meaning |
|---|---|
201 | Write successful |
200 | Read successful |
400 | Invalid request — check the errors object |
404 | File not found — wrong input type for your connector type |
409 | Output file size limit exceeded |
429 | Rate limit exceeded (logs or notifications) |
500 | Internal server error |
See Troubleshooting for detailed fixes for each error.
Generating a typed client
The Container API publishes an OpenAPI specification. You can generate a typed client in any language using tools like OpenAPI Generator or oapi-codegen (Go).
For the full endpoint reference, see API Reference.
How is this guide?