Create a data source

post/v1/datasets/{datasetId}/sources

Connects a store to a dataset. The only supported type today is shopify-api, which reads the public storefront catalogue at https://<store>.myshopify.com/products.json. You can pass either the full products.json URL or the bare store origin; the sync worker appends /products.json and pages through the catalogue 250 products at a time.

syncPeriod controls automatic syncing, in minutes. A source is due when at least syncPeriod minutes have passed since its last successful sync (a source that has never synced is due immediately), at which point the scheduler enqueues a sync job for it. Pass 0 to disable automatic syncing and trigger jobs yourself with Create sync job. Only active sources are scheduled, and only active sources accept manual jobs.

disableGenerativeAssets is accepted but AI-generated thumbnails are currently turned off platform-wide, so the stored value is always true.

Creating a source does not start a sync. Trigger one explicitly, or wait for the scheduler.

The response is 200, not 201.

Private keyapi.v1.datasets.sources.createNo demo

Path parameters

1
datasetIdstring (uuid)required

The dataset the source will feed. Must belong to your organization.

Request body

application/jsonrequired
typestringrequired

Connector type. Only shopify-api is supported.

One ofshopify-api
endpointstring (uri)required

Absolute URL of the store's public products.json endpoint, or the store origin. Must parse as a URL.

syncPeriodintegerrequired

Automatic sync interval in minutes. Must be a JSON number: 0 (never sync automatically) or at least 60. Strings are rejected on create.

min: 0
statusstringrequired

Whether the source is scheduled and accepts sync jobs.

One ofactiveinactive
disableGenerativeAssetsboolean

Accepted for forward compatibility; currently always stored as true.

default: true

Response

200The source was created.
successbooleanrequired

Always true on a 2xx response.

DataSourcerequired

A store connection that feeds a dataset. Sources carry no credentials: the Shopify connector reads the public storefront catalogue, so the only stored configuration is the endpoint URL. Nothing is redacted from responses.

sourceIdstring (uuid)required

Unique identifier of the source. Generated on create.

e.g. "8a4d2f1e-3c5b-4e6a-9d7f-2b1c3d4e5f6a"
datasetIdstring (uuid)required

The dataset this source feeds.

e.g. "3f1c2a9e-6b7d-4c1e-9a2b-1d4e5f6a7b8c"
organizationIdstring (uuid)required

The organization that owns the source.

e.g. "5b7e9c1a-2d4f-4a6b-8c1d-9e2f3a4b5c6d"
typestringrequired

Connector type. shopify-api reads a Shopify storefront's public products.json.

One ofshopify-api
statusstringrequired

active sources are picked up by the scheduler and accept manual sync jobs. inactive sources are ignored by the scheduler and reject manual jobs.

One ofactiveinactive
objectrequired

Scheduling state.

objectrequired

Connector configuration.

createdAtstring (date-time)required

When the source was created.

e.g. "2026-08-01T14:22:09.101Z"
updatedAtstring (date-time)required

When the source was last modified, including scheduler updates to sync.previous.

e.g. "2026-09-11T03:00:12.420Z"

Errors

26

Every error is JSON with a single error string unless noted. Match on the status code; the message is for humans.

400
Request body must be valid JSON.

The request body is not parseable JSON. This response carries no rate-limit headers.

400
Request body must be a JSON object.

The request body is empty, an array, or a JSON scalar. This response carries no rate-limit headers.

404
Dataset not found or does not belong to organization

No dataset with that datasetId belongs to the organization that owns the key. Checked after field validation.

422
type must be "shopify-api"

type is missing or is anything other than shopify-api, and it is the only invalid field.

422
endpoint is required and must be a string

endpoint is missing, empty, or not a string, and it is the only invalid field.

422
endpoint must be a valid URL

endpoint is a string that does not parse as an absolute URL, and it is the only invalid field.

422
syncPeriod is required and must be 0 (Never) or at least 60 minutes

syncPeriod is missing, not a JSON number, or a number between 1 and 59, and it is the only invalid field.

422
status must be "active" or "inactive"

status is missing or not one of the two allowed values, and it is the only invalid field.

422
Validation failed.

More than one field is invalid. details lists one { path, message } entry per invalid field, using the messages above. A single-field failure also carries details.

{
  "error": "Validation failed.",
  "details": [
    {
      "path": "type",
      "message": "type must be \"shopify-api\""
    },
    {
      "path": "syncPeriod",
      "message": "syncPeriod is required and must be 0 (Never) or at least 60 minutes"
    }
  ]
}
curl -X POST "https://stylor.ai/api/v1/datasets/YOUR_DATASET_ID/sources" \
  -H "Authorization: Bearer $STYLOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "type": "shopify-api",
  "endpoint": "https://example-store.myshopify.com/products.json",
  "syncPeriod": 1440,
  "status": "active"
}'
Response · 200
{
  "success": true,
  "source": {
    "sourceId": "8a4d2f1e-3c5b-4e6a-9d7f-2b1c3d4e5f6a",
    "datasetId": "3f1c2a9e-6b7d-4c1e-9a2b-1d4e5f6a7b8c",
    "organizationId": "5b7e9c1a-2d4f-4a6b-8c1d-9e2f3a4b5c6d",
    "type": "shopify-api",
    "status": "active",
    "sync": {
      "period": 1440,
      "previous": null
    },
    "config": {
      "endpoint": "https://example-store.myshopify.com/products.json",
      "disableGenerativeAssets": true
    },
    "createdAt": "2026-09-12T09:15:41.002Z",
    "updatedAt": "2026-09-12T09:15:41.002Z"
  }
}