Upsert (create or update) records into a stream

Note: This endpoint is only available for mutable streams.

Before a user can upsert records, all referenced schema elements (Spaces, Containers, Properties) must be defined/created in Data Modeling.

To upsert records, the user must have capabilities to access (read to) the referenced containers as well as capabilities to access (write to) the referenced record space.

Batches of records are ingested or updated into a stream.

Under normal upsert operation, the record will be created or updated, and the properties defined in each of the containers in the sources array will be populated.

If record identifiers (space + externalId) are already in the stream, records are fully updated (no partial updates for this endpoint). Otherwise, records are created.

Note: The maximum total request size is 10MB.

Securityoidc-token or oauth2-client-credentials or oauth2-open-industrial-data or oauth2-auth-code
Request
path Parameters
streamId
required
string [ 1 .. 100 ] characters ^[a-z]([a-z0-9_-]{0,98}[a-z0-9])?$

An identifier of the stream where the records are stored.

Example: test1
Request Body schema: application/json
required

Records to upsert into a stream.

required
Array of objects (recordItems) [ 1 .. 1000 ] items

List of records to write.

Responses
202

An empty response is returned if all records from the request are successfully accepted to be created or updated.

400

The response for a failed request.

409

Some records with the specified space and externalId are being concurrently modified by this and other requests. But some records might have been created or updated successfully. Which records were successfully upserted and which were rejected with a conflict can be understood from the response content.

Note: better to check which records are in the stream when you receive this error. .../records/filter or .../records/sync endpoints with a filter by space and externalId can be used to check the stored state of the conflicting records.

422

Some record identifiers (space and externalId) are duplicated in the request or attempt to modify records in an immutable stream.

500

If at least one record was not upserted due to an internal error, and all other errors in the failed list were non-retryable, this error code will be returned.

Note: Record operations are not transactional. This means that during batch upsert, some records may be created/updated successfully even if the creation/updating of others fails. The response body indicates which records were successfully upserted and which were not.

An internal server error usually indicates an issue that requires investigation. A simple retry might not help, but a few retries could be a reasonable approach.

Note: If you choose to retry on a 500 error, it is recommended to retry only the failed records rather than the entire request. This helps avoid receiving 409 status codes or overriding records to outdated state (if multiple threads update records in your app).

503

If at least one record was not upserted due to the service being temporarily unavailable, this error code will be returned.

Note: Record operations are not transactional. This means that during batch upsert, some records may be created/updated successfully even if the creation/updating of others fails. The response body indicates which records were successfully upserted and which were not.

A "service temporarily unavailable" error usually indicates a temporary issue, and several retries may help complete the record upserting.

Note: It is recommended to retry only the failed records rather than the entire request. This helps avoid receiving 409 status codes or overriding records to outdated state (if multiple threads update records in your app).

post/streams/{streamId}/records/upsert
Request samples
application/json
{
  • "items": [
    • {
      }
    ]
}
Response samples
application/json
{ }