Productsup
Stream API

Getting started

Create a stream, upload your first products, link the stream to a site, and check the import status.

8 min read

This guide takes you through a basic Stream API integration end to end — you create a stream, upload three products to it, link the stream to a site, trigger an import, and inspect the result.

Prerequisites

  • A Personal Access Token. See Authentication.
  • Familiarity with the terms in the Glossary.
  • A site in the Productsup platform to use for this tutorial.
  • An HTTP client. The examples are curl commands you can run in a terminal or import into Postman.

Replace the <token> placeholder with your Personal Access Token in every request. Replace <stream_id>, <site_id>, and <batch_id> with the values you receive along the way. If you import these commands into Postman, substitute the placeholders first.

Create your first stream

Create the stream that holds your product data. Change the name attribute if you want, but leave type as chunked — it is the default and the right choice for this tutorial. See stream types for the differences.

Request
curl --location --request POST 'https://stream-api.productsup.com/streams' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/vnd.api+json' \
--header 'Accept: application/vnd.api+json' \
--data-raw '{
  "data": {
    "type": "stream",
    "attributes": {
      "name": "Getting started tutorial My first stream",
      "type": "chunked"
    }
  }
}'
Response
{
  "data": {
    "type": "stream",
    "id": "<stream_id>",
    "attributes": {
      "name": "Getting started tutorial My first stream",
      "type": "chunked",
      "createdAt": "2022-11-23T18:07:45+01:00",
      "updatedAt": "2022-11-23T18:07:45+01:00"
    },
    "relationships": {
      "account": {
        "data": {
          "type": "account",
          "id": "<account_id>"
        }
      }
    }
  }
}

The response returns real values in place of the <stream_id> and <account_id> placeholders.

Save the stream ID. You need it in the requests that follow.

List your streams

List the streams in your account to confirm the new one is there.

Request
curl --location --request GET 'https://stream-api.productsup.com/streams' \
--header 'Authorization: Bearer <token>' \
--header 'Accept: application/vnd.api+json'
Response
{
  "data": {
    "type": "stream",
    "id": "<stream_id>",
    "attributes": {
      "name": "Getting started tutorial My first stream",
      "type": "chunked",
      "createdAt": "2022-11-23T18:07:45+01:00",
      "updatedAt": "2022-11-23T18:07:45+01:00"
    },
    "relationships": {
      "account": {
        "data": {
          "type": "account",
          "id": "<account_id>"
        }
      }
    }
  }
}

This endpoint returns all streams in your account, so the response also lists any streams that existed before this tutorial.

See List stream for pagination and for retrieving an individual stream.

Upload data to your stream

Upload three products to the stream you created. Chunked streams take product data in the NDJSON format. Replace <stream_id> in the request URL with the stream ID from step 1.

The second product in the example carries a deliberate syntax error. It is part of the tutorial — you see its effect in step 6.

Request
curl --location --request POST 'https://stream-api.productsup.com/streams/<stream_id>/products' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/x-ndjson' \
--header 'Accept: application/vnd.api+json' \
--data-binary @- <<EOF
{"id":"34SKJDF42DF","name":"Product 1","company":"ACME Corp.","price":100}
{"id":"475-SHIRT-XL","name":"Product 2","company":"ACME Corp.","price":15", "size":"XL"}
{"id":7824796324,"name":"Product 3","company":"ACME Corp.","price":5,"sale_price":4.5, "size":""}
EOF
Response
{
  "data": {
    "type": "batch",
    "id": "<batch_id>",
    "attributes": {
      "status": "uploaded",
      "errorCount": 1,
      "stages": {
        "upload": {
          "completedAt": "2022-11-25T15:40:10+01:00",
          "status": "warning",
          "successCount": 2,
          "errorCount": 1,
          "errors": [
            {
              "message": "Syntax error",
              "occurrences": 1,
              "example": {
                "lineNumber": 2,
                "value": "{\"id\":\"475-SHIRT-XL\",\"name\":\"Product 2\",\"company\":\"ACME Corp.\",\"price\":15\", \"size\":\"XL\"}"
              }
            }
          ]
        },
        "processing": null
      }
    }
  },
  "relationships": {
    "stream": {
      "data": {
        "type": "stream",
        "id": "<stream_id>"
      }
    }
  }
}

The response reports validation errors immediately. The status, successCount, and errorCount attributes tell you how the upload went. Products are parsed individually, so partial uploads happen — here two products upload cleanly and the malformed one is rejected.

The returned id is the Batch ID, a unique reference to this upload. Save it for step 6.

The Stream API accepts only flat JSON objects with scalar attribute values. See Uploading data and API standards.

We maintain strict rate limits on all upload endpoints. See Rate limiting. We recommend you implement a retry and exponential backoff mechanism.

Create a Stream API data source

A data source lets the platform import product data from a stream into a site. Submit the stream ID from step 1 in the stream_id attribute to link the site to the stream, and replace <site_id> with the site you are using for this tutorial. The description is what the platform shows when listing data sources.

If you have no site available, skip steps 4 and 5 — both operate on a site.

The domain changes here. This endpoint belongs to the Platform API, the account management API. Endpoints that matter for a Stream API integration support unified authentication, so your Personal Access Token works on them.

Request
curl --location --request POST 'https://platform-api.productsup.io/platform/v2/sites/<site_id>/streams' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data-raw '{
  "import_type": 1,
  "description": "Stream API Tutorial - First Stream API Data Source",
  "stream_id": <stream_id>,
  "status": "active"
}'
Response
{
  "success": true,
  "Sources": [
    {
      "id": "<data_source_id>",
      "site_id": "<site_id>",
      "description": "Stream API Tutorial - First Stream API Data Source",
      "source": "",
      "import_type": 1,
      "import_id": 331,
      "status": "active",
      "settings": [
        "stream : <stream_id>"
      ]
    }
  ]
}

The settings array confirms which stream the data source reads from.

See Create stream data source for the full field reference.

Import your first products

With the data source configured, trigger an import to move the stream data into your site. This call does the same thing as the Import button in the platform. Replace <site_id> with the site you are using for this tutorial.

This endpoint also belongs to the Platform API and supports unified authentication.

Request
curl --location --request POST 'https://platform-api.productsup.io/platform/v2/process/<site_id>' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data-raw '{"action": "import"}'
Response
{
  "success": true,
  "process_id": "<process_id>"
}

The response confirms that the process was scheduled and returns a process_id identifying the run.

See Process for the full field reference and for the other actions this endpoint accepts.

Check the status of your upload

Check what happened to the products you uploaded in step 3. Replace <stream_id> and <batch_id> with your own values.

Access to the batch status endpoint is disabled by default for performance reasons. To get access, contact your Productsup Customer Success Manager or our Technical Support Team via support@productsup.com.

Batch statuses are cached for 48 hours only. If you take longer than that between steps, this request can fail.

Request
curl --location --request GET 'https://stream-api.productsup.com/streams/<stream_id>/batches/<batch_id>' \
--header 'Authorization: Bearer <token>' \
--header 'Accept: application/vnd.api+json'
Response
{
  "data": {
    "type": "batch",
    "id": "<batch_id>",
    "attributes": {
      "status": "processed",
      "errorCount": 1,
      "stages": {
        "upload": {
          "completedAt": "2022-11-25T15:40:10+01:00",
          "status": "warning",
          "successCount": 2,
          "errorCount": 1,
          "errors": [
            {
              "message": "Syntax error",
              "occurrences": 1,
              "example": {
                "lineNumber": 2,
                "value": "{\"id\":\"475-SHIRT-XL\",\"name\":\"Product 2\",\"company\":\"ACME Corp.\",\"price\":15\", \"size\":\"XL\"}"
              }
            }
          ]
        },
        "processing": {
          "completedAt": "2022-11-25T15:50:45+01:00",
          "status": "success",
          "successCount": 2,
          "errorCount": 0,
          "errors": []
        }
      }
    },
    "relationships": {
      "stream": {
        "data": {
          "type": "stream",
          "id": "<stream_id>"
        }
      }
    }
  }
}

The batch status now reads processed, meaning the batch finished importing into the platform. In step 3 it read uploaded, which only confirmed the upload that precedes the import.

The response breaks the batch down by stage:

AttributeDescription
errorCount (top level)Total number of errors across both stages
stagesThe upload and processing stages, each with their own event details
status (per stage)Overall status of all events during that stage
successCount, errorCount (per stage)Number of products imported successfully or unsuccessfully
errors (per stage)Details about the affected products and the reason for the failure

Only products that pass a stage continue to the next one, which is why successCount is 2 in both stages while the syntax error from step 3 is still reported against the upload stage.

See Batches for more information.

Next steps

  • Uploading data — request formats, payload rules, and attribute requirements
  • streams — stream types, formats, and data retention
  • Import setup — platform-side configuration and recommendations
  • Rate limiting — limits, timeouts, and retry mechanisms

On this page

Still stuck?

Reach out to our support team and we’ll help you get unstuck.

Contact support