openapi: 3.2.0 info: title: Experience APIs for API Sections API only API version: '2.2' description: API-only mode endpoints, for users who want to use the Experience APIs without using the full Experience OS features. In API-only mode, you are responsible for generating user and session IDs, and for reporting pageviews and events, while still benefiting from Dynamic Yield's personalization capabilities. servers: - url: https://dy-api.com/v2 security: - sec0: [] tags: - name: API only description: API-only mode endpoints, for users who want to use the Experience APIs without using the full Experience OS features. In API-only mode, you are responsible for generating user and session IDs, and for reporting pageviews and events, while still benefiting from Dynamic Yield's personalization capabilities. paths: /collect/user/engagement (API only): post: summary: Reporting Engagement - API site description: 'Report user engagement (clicks) over a variation or a recommended item. Select your endpoint from the Base URL dropdown. If you are not sure which server URL you should use, see here.' operationId: reporting-engagement-2 tags: - API only requestBody: content: application/json: schema: type: object properties: user: properties: id: type: string description: The User ID. In API-site implementations, you are responsible for generating IDs for new users, and persisting them for existing ones. required: - id type: object session: properties: custom: type: string description: The Session ID In API-site implementations, the identifier is for you to generate & persist. required: - custom type: object context: properties: device: properties: ip: type: string description: The client IP address, for IP filtering. If not passed, the IP of the caller is used. *Optional* default: 54.100.200.255 type: object type: object engagements: type: array description: One or more engagements with a variation. This is where you report the type of engagement together with a reference to the content or recommendation that the user engaged with. If you wish to report on impression or slot impression, set the implicit impression to false in the choose request (otherwise impression numbers will be doubled in the reports). items: properties: type: type: string description: Pass the value *CLICK* or *IMP* (impressions) for API Custom Code Campaigns; pass the value *SLOT_CLICK* for API Recommendations campaigns, pass the value *PN_CLICK* to track click on Reconnect Push Notifications, pass the value *PN_IMP* to track Reconnect Push Notification delivery, pass the value *SLOT_IMP* for QSR Recommendations campaigns only enum: - CLICK - IMP - SLOT_CLICK - PN_CLICK - PN_IMP - SLOT_IMP decisionId: type: string description: '**Required for reporting CLICK or IMP**: The unique Decision ID as returned from the `choose` endpoint.' variations: type: array description: 'Only required for reporting explicit impressions over Custom Campaigns which return multiple variations on each decision (e.g. a slider)**: an array of multiple variation IDs the user seen.' default: [] items: type: integer format: int32 slotId: type: string description: '**Required for reporting a click on an API Recommendations Campaign**: The Slot ID for the specific clicked product as returned from the `choose` endpoint. *Not used for Custom API Campaigns*.' trackingData: type: string required: - type type: object responses: '204': description: '204' content: application/json: examples: Success (no body returned): value: ' ' '400': description: '400' content: application/json: examples: Result: value: '{}' schema: type: object properties: {} deprecated: false x-readme: code-samples: - language: javascript code: "var request = require(\"request\");\n\nvar options = {\n method: 'POST',\n url: 'https://dy-api.com/v2/collect/user/engagement',\n headers: {'content-type': 'application/json', 'dy-api-key': 'your-api-key'},\n body: `{\n \"user\": {\n \"id\": \"myuser123abc\"\n },\n \"session\": {\n \"custom\": \"custsession123\"\n },\n \"context\": {\n \"device\": {\n \"ip\": \"54.100.200.255\"\n }},\n \"engagements\": [\n {\n \"decisionId\": \"l7MxODY3NDc5MDc2Mjg2ODUzMTExe6MyMzShMcCRB84AAWWz\",\n \"type\": \"IMP\"\n },\n\t\t\t{\n \"decisionId\": \"l7MxODY3NDc5MDc2Mjg2ODUzMTExe6MyMzShMcCRB84AAWWz\",\n \"type\": \"CLICK\"\n },\n {\n \"type\": \"SLOT_CLICK\",\n \"slotId\": \"l4SkdHlwZahDQVRFR09SWahsb2NhdGlvbtoAL2h0dHBzOi8vc2hvcC53ZWJzaXRlLmNvbS9tZW4tcGFudHMvcDczODM3MjMtMDEwpGRhdGGQqHJlZmVycmVysHd3dy5yZWZlcnJlci5jb23NLwrNeyvCAKsxMjAxMTIzLTAwNwE=*l7MxODY3NDc5MDc2Mjg2ODUzMjAyzQI3ozIzNKExwJEHzgABZbM=\"\n },\n {\n \"type\": \"SLOT_IMP\",\n \"slotIds\": [\"l4SkdHlwZahDQVRFR09SWahsb2NhdGlvbtoAL2h0dHBzOi8vc2hvcC53ZWJzaXRlLmNvbS9tZW4tcGFudHMvcDczODM3MjMtMDEwpGRhdGGQqHJlZmVycmVysHd3dy5yZWZlcnJlci5jb23NLwrNeyvCAKsxMjAxMTIzLTAwNwE=*l7MxODY3NDc5MDc2Mjg2ODUzMjAyzQI3ozIzNKExwJEHzgABZbM=\"]\n }\n ]}`\n};\n\nrequest(options, function (error, response, body) {\n if (error) throw new Error(error);\n\n console.log(body);\n});" name: 'API-Only Mode: Engagement request (Node.JS)' samples-languages: - javascript /collect/user/event (API only): post: summary: Reporting Events - API site description: 'Report a predefined or custom event. Select your endpoint from the Base URL dropdown. If you are not sure which server URL you should use, see here.' operationId: reporting-events-api-only tags: - API only requestBody: content: application/json: schema: type: object required: - events properties: user: properties: id: type: string description: The User ID.. In API-Only Mode, you are responsible for generating IDs for new users, and persisting them for existing ones. required: - id type: object session: properties: custom: type: string description: The Session ID. In API-Only Mode, the identifier is for you to generate & persist. required: - custom type: object context: properties: device: properties: ip: type: string description: The client IP address, for IP filtering. If not passed, the IP of the caller is used. *Optional* default: 54.100.200.255 type: object type: object events: type: array description: One or more events to report responses: '204': description: '204' content: application/json: examples: Success (no body returned): value: ' ' deprecated: false x-readme: code-samples: - language: javascript code: "var request = require(\"request\");\n\nvar options = {\n method: 'POST',\n url: 'https://dy-api.com/v2/collect/user/event',\n headers: {'content-type': 'application/json', 'dy-api-key': 'your-api-key'},\n body: `{\n \"user\": {\n \"id\": \"myuser123abc\"\n },\n \"session\": {\n \"custom\": \"custsession123\"\n },\n \"context\": {\n \"device\": {\n \"ip\": \"54.100.200.255\"\n }},\n \"events\": [{\n \t\"name\": \"myEvent123\",\n \t\"properties\":{}\n }]}`\n};\n\nrequest(options, function (error, response, body) {\n if (error) throw new Error(error);\n\n console.log(body);\n});" name: 'API-Only Mode: Event request (Node.JS)' samples-languages: - javascript /collect/user/pageview (API only): post: summary: Reporting Pageviews - API site description: 'Report a pageview without choosing variations for any campaigns. Select your endpoint from the Base URL dropdown. If you are not sure which server URL you should use, see here.' operationId: reporting-pageviews-api-only tags: - API only requestBody: content: application/json: schema: type: object properties: user: properties: id: type: string description: The User ID.. In API-Only Mode, you are responsible for generating IDs for new users, and persisting them for existing ones. required: - id type: object session: properties: custom: type: string description: The Session ID In API-Only Mode, the identifier is for you to generate & persist. required: - custom type: object context: properties: page: properties: type: type: string description: Page type, such as HOMEPAGE, CATEGORY, PRODUCT, etc. See Developer Guide for listing. default: PRODUCT data: type: array description: Additional data related to the page type, such as the product SKU for PRODUCT-type pages. Detailed in the Developer Guide. default: - p76311-020 items: type: string location: type: string description: Page URL (for web), location (for SPAs), or screen name (for mobile apps) default: https://shop.biz/nice-shirt-p76311.html referrer: type: string description: Page referrer, if available. *Optional* default: https://google.cz locale: type: string description: Page locale, such as "en_US". *Optional* default: de_DE required: - type - data - location type: object device: properties: userAgent: type: string description: For web-based clients, the User-Agent string. If not passed, the API Gateway will check for that header in the HTTPS request. *Optional* default: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 ip: type: string description: The client IP address, for geolocation-based targeting and audience building. If not passed, the IP of the caller is used. *Optional* default: 54.100.200.255 type: object type: object responses: '204': description: '204' content: text/plain: examples: Success (no body returned): value: deprecated: false x-readme: code-samples: - language: javascript code: "var request = require(\"request\");\n\nvar options = {\n method: 'POST',\n url: 'https://dy-api.com/v2/collect/user/pageview',\n headers: {'content-type': 'application/json', 'dy-api-key': 'your-api-key'},\n body: `{\n \"user\": {\n \t\"id\": \"myuser123abc\"\n },\n \"session\": {\n \"custom\": \"custsession123\"\n },\n \"context\": {\n \"page\": {\n \"type\": \"PRODUCT\",\n \"location\": \"https://shop.biz/nice-shirt-p76311.html\",\n \"referrer\": \"https://google.cz\",\n \"locale\": \"de_DE\"\n },\n \"device\": {\n \"userAgent\": \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\",\n \"ip\": \"54.100.200.255\"\n }\n }}`\n};\n\nrequest(options, function (error, response, body) {\n if (error) throw new Error(error);\n\n console.log(body);\n});" name: 'API-Only Mode: Pageview request (Node.JS)' samples-languages: - javascript /serve/user/choose (API only): post: summary: Choosing Variations - API site description: 'Get chosen variations for one or more campaigns, either Custom Campaigns or Recommendations. By default also reports a new pageview with the given context. Select your endpoint from the Base URL dropdown. If you are not sure which server URL you should use, see here.' operationId: choosing-variations-api-only tags: - API only requestBody: content: application/json: schema: type: object properties: user: properties: id: type: string description: The User ID. In API-only mode, you are responsible for generating IDs for new users, and persisting them for existing ones. required: - id type: object session: properties: custom: type: string description: The Session ID. In API-Only Mode you should generate & persist this ID. required: - custom type: object selector: properties: names: type: array description: Array of Dynamic Yield campaign names to choose variations for. Pass the *API Selector Name* of campaigns rather than the display name, which may change by the Admin UI User. Names are case-insensitive, but whitespace-sensitive. An empty list is valid. default: - Banner Main - German Banner - PDP Recs Tray" items: type: string groups: type: array description: All the active campaign selectors in the group are sent back in the response to your CHOOSE call, the definition of the group is done in the Experience OS console. items: type: string preview: type: object description: Preview token IDs, as passed by the dyApiPreview URL parameter on preview properties: {} required: - names type: object context: properties: page: properties: type: type: string description: Page type, such as HOMEPAGE, CATEGORY, PRODUCT, and so on. See the support site for details. default: HOMEPAGE data: type: array description: Additional data related to the page type, such as the product SKU for PRODUCT-type pages. **Required only for Category and Product pages**. Do not use for Homepage or other types. See more details on the support site. items: type: string location: type: string description: Page URL (for web), location (for SPAs), or screen name (for mobile apps) default: https://shop.biz/index.html referrer: type: string description: Page referrer, if available. *Optional* locale: type: string description: Page locale, such as "en_US". Should be sent in each request when using the localized content feature. *Optional* default: en_US required: - type - data - location type: object device: properties: userAgent: type: string description: For web-based clients, the User-Agent string. If not passed, the API Gateway will check for that header in the HTTPS request. *Optional* default: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 ip: type: string description: The client IP address, for geolocation-based targeting and audience building. If not passed, the IP of the caller is used. *Optional* default: 54.100.200.255 dateTime: type: string description: 'Date & time in ISO 8601 format: YYYY-MM-DDThh:mm:ss.sss±hh:mm (with local time zone). *Optional*.' type: object pageAttributes: type: object description: A shallow object of custom attributes that can be used for campaign targeting in the Experience OS console. *Optional* properties: {} type: object options: properties: isImplicitPageview: type: boolean description: 'Whether to report a new pageview with the given context. In API-only Mode this value is *true* by default. Note that if you''re calling `choose` more than once for a page , you should make sure that a pageview is reported only once: Either set this to parameter to *false* in all but one of your `choose` calls, or for a less error-prone approach: always pass *false*, and use the dedicated `pageview` endpoint to report all pageviews.' default: true ' returnAnalyticsMetadata': type: boolean description: Whether to return additional metadata (display names & IDs for all entities) useful for reporting to analytics tools default: false recsProductData: properties: skusOnly: type: boolean description: To reduce the size of the response, you can limit it so that it only includes the SKUs ' fieldFilter': type: array description: Specify the fields you need in the recommendation campaign response by using the “fieldFilter” parameter. Simply send an array of strings of the relevant fields, and only those fields and values are sent back. items: type: string type: object type: object responses: '200': description: '200' content: application/json: examples: Result: value: "{\n \"choices\": [\n {\n \"id\": 484687,\n \"name\": \"test1\",\n \"type\": \"DECISION\",\n \"variations\": [\n {\n \"id\": 21831162,\n \"payload\": {\n \"type\": \"CUSTOM_JSON\",\n \"data\": {\n \"hello\": 1\n }\n }\n }\n ],\n \"decisionId\": \"l7QtNjM5NDkxMzUzMDQ1MjE4NjYyMs4ADcQTpzgyODQwMDEBkJHOAU0d+qUzMjc3Mw==\"\n }\n ]\n}" schema: type: object properties: choices: type: array items: type: object properties: id: type: integer example: 484687 default: 0 name: type: string example: test1 type: type: string example: DECISION variations: type: array items: type: object properties: id: type: integer example: 21831162 default: 0 payload: type: object properties: type: type: string example: CUSTOM_JSON data: type: object properties: hello: type: integer example: 1 default: 0 decisionId: type: string example: l7QtNjM5NDkxMzUzMDQ1MjE4NjYyMs4ADcQTpzgyODQwMDEBkJHOAU0d+qUzMjc3Mw== '400': description: '400' content: application/json: examples: Result: value: '{}' schema: type: object properties: {} deprecated: false x-readme: code-samples: - language: javascript code: "var request = require(\"request\");\n\nvar options = {\n method: 'POST',\n url: 'https://dy-api.com/v2/serve/user/choose',\n headers: {'content-type': 'application/json', 'dy-api-key': 'your-api-key'},\n body: `{\n \"selector\": {\n \"names\": [\n \"test1\"\n ]\n },\n \"user\": {\n \"id\": \"customUserId123\"\n },\n \"session\": {\n \"custom\": \"myCustomSession345\"\n },\n \"context\": {\n \"page\": {\n \"type\": \"HOMEPAGE\",\n \"location\": \"https://example.org\",\n \"locale\": \"en_US\",\n \"data\":[]\n },\n \"device\": {\n \"userAgent\": \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\",\n \"ip\": \"54.100.200.255\"\n }\n },\n \"options\": {\n \"isImplicitPageview\": false,\n \" returnAnalyticsMetadata\": false\n }}`\n};\n\nrequest(options, function (error, response, body) {\n if (error) throw new Error(error);\n\n console.log(body);\n});\n\n" name: API-only example (Node.JS) - language: javascript code: "func postActiona() {\n let data = [\n \"user\": [\n \"id\": \"yaeaaa477y723hania\"\n ],\n \"session\": [\n \"custom\": \"iqudddcd4gff2fashe2koh\"\n ],\n \"selector\": [\n \"names\": [\n \"PDP Top Banner\",\n \"PDP Recs\"\n ]\n ],\n \"context\": [\n \"page\": [\n \"type\": \"PRODUCT\",\n \"data\": [\"7383723-010\"],\n \"location\": \"https://sugoi-ne.com/men-pants/p7383723-010\",\n \"referrer\": \"https://sugoi-ne.com/men-pants\",\n \"locale\": \"en_US\"\n ],\n \"device\": [\n \"userAgent\": \"Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X)\",\n \"ip\": \"54.100.200.255\"\n ],\n \"pageAttributes\": [\n \"customPageAttribute\": \"someValue\"\n ]\n ],\n \"options\": [\n \"isImplicitPageview\": true\n ]\n ];\n let serviceUrl = URL(string: \"https://dy-api.com/v2/serve/user/choose\")!\n var request = URLRequest(url: serviceUrl)\n request.httpMethod = \"POST\"\n request.setValue(\"Application/json\", forHTTPHeaderField: \"Content-Type\")\n request.setValue(\"69891577675178c7f8ce0767ded46402f9a97fa7fad1bae5d340e6d9673a9d1f\", forHTTPHeaderField: \"DY-API-Key\")\n guard let httpBody = try? JSONSerialization.data(withJSONObject: data, options: []) else {\n return\n }\n request.httpBody = httpBody\n let session = URLSession.shared\n session.dataTask(with: request) { (data, response, error) in\n if let data = data {\n do {\n let json = try JSONSerialization.jsonObject(with: data, options: [])\n print(json)\n } catch {\n print(error)\n }\n }\n }.resume()\n }" name: iOS API-only example - language: javascript code: "suspend fun sendPostRequest() = withContext(Dispatchers.IO) {\n val data = \"{\" +\n \" \\\"user\\\": {\" +\n \" \\\"id\\\": \\\"yaeaaa477y723hania\\\"\" +\n \" },\" +\n \" \\\"session\\\": {\" +\n \" \\\"custom\\\": \\\"iqudddcd4gff2fashe2koh\\\"\" +\n \" },\" +\n \" \\\"selector\\\": {\" +\n \" \\\"names\\\": [\" +\n \" \\\"PDP Top Banner\\\",\" +\n \" \\\"PDP Recs\\\"\" +\n \" ]\" +\n \" },\" +\n \" \\\"context\\\": {\" +\n \" \\\"page\\\": {\" +\n \" \\\"type\\\": \\\"HOMEPAGE\\\",\" +\n \" \\\"data\\\": [],\" +\n \" \\\"location\\\": \\\"https://sugoi-ne.com/men-pants/p7383723-010\\\",\" +\n \" \\\"referrer\\\": \\\"https://sugoi-ne.com/men-pants\\\",\" +\n \" \\\"locale\\\": \\\"en_US\\\"\" +\n \" },\" +\n \" \\\"device\\\": {\" +\n \" \\\"userAgent\\\": \\\"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\\\",\" +\n \" \\\"ip\\\": \\\"54.100.200.255\\\"\" +\n \" },\" +\n \" \\\"pageAttributes\\\": {\" +\n \" \\\"customPageAttribute\\\": \\\"someValue\\\"\" +\n \" }\" +\n \" },\" +\n \" \\\"options\\\": {\" +\n \" \\\"isImplicitPageview\\\": true\" +\n \" }\" +\n \"}\"\n\n val mURL = URL(\"https://dy-api.com/v2/serve/user/choose\")\n\n with(mURL.openConnection() as HttpURLConnection) {\n requestMethod = \"POST\"\n setRequestProperty(\"Content-Type\", \"application/json; charset=utf-8\")\n setRequestProperty(\"DY-API-Key\", \"69891577675178c7f8ce0767ded46402f9a97fa7fad1bae5d340e6d9673a9d1f\")\n\n doOutput = true\n val outputWriter = OutputStreamWriter(outputStream)\n outputWriter.write(data)\n outputWriter.flush()\n\n println(\"URL : $url\")\n println(\"Response Code : $responseCode\")\n\n BufferedReader(InputStreamReader(inputStream)).use {\n val response = StringBuffer()\n\n var inputLine = it.readLine()\n while (inputLine != null) {\n response.append(inputLine)\n inputLine = it.readLine()\n }\n println(\"Response : $response\")\n }\n }\n}" name: Android API-only example samples-languages: - javascript components: securitySchemes: sec0: type: apiKey in: header name: DY-API-Key x-default: your-api-key x-provenance: method: searched source: https://dy.dev/reference harvested: '2026-10-14' tool: harvest-readme-openapi.py note: Assembled verbatim from the OpenAPI definition ReadMe embeds in each operation page of the provider's developer portal; paths and components merged by API title, nothing authored. assembled_from: - https://dy.dev/reference/choosing-variations-api-only.md - https://dy.dev/reference/reporting-engagement-2.md - https://dy.dev/reference/reporting-events-api-only.md - https://dy.dev/reference/reporting-pageviews-api-only.md merge: pages: 4 deduped: 3 conflicts_kept_first: 0