{
  "openapi": "3.0.0",
  "info": {
    "title": "Zoined Partner & Retail Analytics Portal API",
    "version": null,
    "description": "This documentation contains two Zoined APIs for partner integrations and access to the Zoined Analytics Portal.\n\n**Zone — Zoined Partner API**\n\nZoined Partner API allows partners to manage their customers via RESTful API.\n\n---\n**SSO API — Zoined Retail Analytics Portal**\n\nZoined Retail Analytics Portal provides API for implementing Single Sign-On (SSO) via\nsession transfer url. This allows logged in end users of customers or partners system to start\nusing Zoined Analytics Portal without separately logging in. This is accomplished\nby sending Zoined information about the end user with untamperable link.\n"
  },
  "servers": [
    {
      "url": "https://app.zoined.com",
      "description": "Zoined Retail Analytics Portal"
    },
    {
      "url": "https://partners.zoined.com",
      "description": "Zoined Partner API"
    }
  ],
  "tags": [
    {
      "name": "portal-overview",
      "x-displayName": "SSO-API Overview",
      "description": "Zoined Retail Analytics Portal provides API for implementing Single Sign-On (SSO) via\nsession transfer url. This allows logged in end users of customers or partners system to start\nusing Zoined Analytics Portal without separately logging in. This is accomplished\nby sending Zoined information about the end user with untamperable link.\n\n[SessionTransfer schema](#schema/SessionTransfer)\n"
    },
    {
      "name": "portal-session-transfer",
      "x-displayName": "Session transfer",
      "description": "Session transfer allows you to transfer logged in end user from the system you control\ninto Zoined as logged in user. This is accomplished by creating JSON message with the\ninformation about the user and then signing it with cryptographic digest to ensure\nthat message comes from your system and is not tampered with. Payload JSON message\nstructure can be seen above.\n\nAfter payload JSON is created, digest is calculated from the payload and shared secret\nwhich have been provided to you by Zoined, or retrieved via partner API.\n\nCalculation in pseudocode is shown below:\n\n```\nsha512hex(concatenate(payload, '#', secret))\n```\n\nThere are two ways to implement session transfer to Zoined. First you can create\nlink based on the instructions, and just redirect user to this link. This is easy\nto implement, but drawback is that this request will be stored in users browser\nhistory. Same link cannot be used to log back in due embedded timestamp, but link\ncontains users name, role, and access restrictons, although encoded with Base64.\n\nSecond approach is to make POST request with payload and digest sent as\nPOST parameters. This won't get stored to browser history, but is bit more complicated\nto implement. Server will need to provide payload and digest to web page in your service,\nand after that browser needs to do form submit. This can be accomplished e.g. by\nretrieving data from server via AJAX, filling data to hidden form, and then submitting\nit via Javascript.\n\nPlease note that sending server's time needs to be reasonable synchronized with the\nglobal time, as we are using timestamps from server for checking the time based link\nvalidity. Payloads with timestamp older than 5 minutes will be discarded. Please also\nnote that shared secret must never be transferred to browser, or otherwise it can\nbe used for unauthorized access. Forming of payload, and calculation of digest needs\nto happen strictly on server side.\n"
    },
    {
      "name": "partner-overview",
      "x-displayName": "Zone API Overview",
      "description": "Zoined Partner API allows partners to manage their customers via RESTful API.\n\nThis document contains instructions on how to access the Zoined Partner API. This document\ncontains two parts: introduction and reference. Introduction walks you through the\ngeneral structure of the API and and how to use it. Reference contains detailed\ndocumentation for each API end point including code examples for multiple programming\nlanguages, and live in-browser testing tool for the API end points.\n\nIf you have any questions related to Zoined Partner API, don't hesitate to contact\n[Zoined support](mailto:support@zoined.com).\n\nSee it live at [https://partners.zoined.com/](https://partners.zoined.com/)\n\n**Authentication:**\nYou'll receive API token from Zoined which grants you access to Zone. Token needs to be added to all HTTP requests made against our API. It should be added as HTTP Headers with following format:\n\n```\nAuthorization: Token token=\"your-token-here\"\n```\n"
    },
    {
      "name": "partner-maintenance",
      "x-displayName": "Maintenance"
    },
    {
      "name": "partner-customers",
      "x-displayName": "Customer",
      "description": "These end points allow you to manage your customers.\n\nDepending whether you are connecting Zoined via database poll or ZAPI, there are some differences in the data associated with each customers.\n\n**ZAPI:** If you are connecting via ZAPI, the returned customer information\ncontains a `token` field with the API token needed to access ZAPI for that customer.\n\n```\n{\n  \"key\": \"Demo company\",\n  ...\n  \"token\": \"abcdefghijklmn\"\n}\n```\n\n**Database poll:** If you are connecting via database fetch, you need to\ndefine additional data source configuration when creating the customer. We'll also return dataSource block which will return the the data source configuration for the customer with password masked.\n\n```json\n{\n  \"dataSource\": {\n    \"host\": \"db-host\",\n    \"port\": 3306,\n    \"database\": \"database_name\",\n    \"username\": \"db-username\",\n    \"password\": \"db-XXXXXXXXXX\",\n    \"filters\": {\n      \"companyId\": \"123\"\n    }\n  }\n}\n```\n"
    },
    {
      "name": "partner-messaging",
      "x-displayName": "Messaging",
      "description": "These end points allow you to broadcast portal messages to either all of your customers\nor only given customers and get view statistics afterwards. Only single message at\na time is supported for both all companies (broadcast) and a single company.\n"
    },
    {
      "name": "portal-data-structures",
      "x-displayName": "Data Structures",
      "description": "Data structures used for SSO session transfer. The `SessionTransfer` object\ndescribes the decoded JSON that is Base64-encoded into the SSO `payload` parameter.\n"
    }
  ],
  "paths": {
    "/sso/session_transfer/{customer_id}": {
      "get": {
        "summary": "Session transfer via URL",
        "description": "Allows user to login with generated URL.\n\n**GET** `https://app.zoined.com/sso/session_transfer/{customer_id}?payload={payload}&digest={digest}`\n",
        "operationId": "portalSessionTransferViaUrl",
        "tags": [
          "portal-session-transfer"
        ],
        "servers": [
          {
            "url": "https://app.zoined.com"
          }
        ],
        "parameters": [
          {
            "name": "customer_id",
            "in": "path",
            "description": "Identifier for the customer account to login to",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "mycompany"
          },
          {
            "name": "payload",
            "in": "query",
            "description": "Base64 encoded JSON message containing user data.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "foo"
          },
          {
            "name": "digest",
            "in": "query",
            "description": "SHA-512 digest calculated from unencoded payload + secret key.",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "bar"
          }
        ],
        "responses": {
          "302": {
            "description": "On success user is redirected to dashboard or target path specified in payload."
          },
          "422": {
            "description": ""
          }
        }
      },
      "post": {
        "summary": "Session transfer via POST request",
        "description": "Login user via SSO POST request.\n\n**POST** `https://app.zoined.com/sso/session_transfer/{customer_id}`\n",
        "operationId": "portalSessionTransferViaPost",
        "tags": [
          "portal-session-transfer"
        ],
        "servers": [
          {
            "url": "https://app.zoined.com"
          }
        ],
        "parameters": [
          {
            "name": "customer_id",
            "in": "path",
            "description": "Identifier for the customer account to login to",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "mycompany"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "payload",
                  "digest"
                ],
                "properties": {
                  "payload": {
                    "type": "string",
                    "description": "Base64 encoded JSON message containing user data.",
                    "example": "payload-content"
                  },
                  "digest": {
                    "type": "string",
                    "description": "SHA-512 digest calculated from unencoded payload + secret key.",
                    "example": "digest-value"
                  }
                }
              },
              "example": {
                "payload": "payload-content",
                "digest": "digest-value"
              }
            }
          }
        },
        "responses": {
          "302": {
            "description": "On success user is redirected to dashboard or target path specified in payload."
          },
          "422": {
            "description": ""
          }
        }
      }
    },
    "/api": {
      "get": {
        "summary": "Check connectivity",
        "description": "This endpoint can be used to verify that you are able to access our API.\n\n**GET** `https://partners.zoined.com/api`\n",
        "operationId": "partnerCheckConnectivity",
        "tags": [
          "partner-maintenance"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Request has been processed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Hello Demo Partner. You have successfully connected to Zoined Partner API."
                    }
                  }
                },
                "example": {
                  "message": "Hello Demo Partner. You have successfully connected to Zoined Partner API."
                }
              }
            }
          }
        }
      }
    },
    "/api/invoicing/{environment}": {
      "get": {
        "summary": "Retrieving invoicing information",
        "description": "Provides monthly invoicing report for last 12 months. Report lists total and per customer cash register, store, and camera counts per month.\n\n**GET** `https://partners.zoined.com/api/invoicing/{environment}`\n",
        "operationId": "partnerGetInvoicingInformation",
        "tags": [
          "partner-maintenance"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "environment",
            "in": "path",
            "description": "Environment to retrieve information for",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "production"
          }
        ],
        "responses": {
          "200": {
            "description": "Request has been processed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoicingResponse"
                },
                "example": {
                  "customers": [
                    "dm_company",
                    "dm_company2"
                  ],
                  "data": [
                    {
                      "customers": [
                        {
                          "customer": "dm_company",
                          "cameras": 14,
                          "registers": 10,
                          "stores": 2
                        },
                        {
                          "customer": "dm_company2",
                          "cameras": 5,
                          "registers": 2,
                          "stores": 1
                        }
                      ],
                      "date": "2016-01",
                      "total": {
                        "cameras": 19,
                        "registers": 12,
                        "stores": 3
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "No partner customers exist in system."
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/customers": {
      "get": {
        "summary": "List customers",
        "description": "Lists all your customers.\n\n**GET** `https://partners.zoined.com/api/customers`\n",
        "operationId": "partnerListCustomers",
        "tags": [
          "partner-customers"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Request has been processed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CustomerResponse"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "No partner customers exist in system."
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "post": {
        "summary": "Create customer",
        "description": "This API endpoint allows you to create new customer. On success you'll receive JSON\nwith key for the newly created customer. Please note that it will take some time to\ninitialize the customer in our systems. Customer's status will be shown as\n`creating` while setup is in progress. Once status changes to `ok` the customer is\nfully operational.\n\nKey can also be left out, in which case we'll create key based on company name.\n\nIf you are using ZAPI to connect customers into Zoined, you should leave out\nthe `dataSource` block in the request. In addition to key, you'll also receive\ncustomers ZAPI token in the response in field `token`.\n\nIf you are using database fetch, you'll need to provide connection credentials in\nthe `dataSource` block. On setups where multiple companies are stored in the same\ndatabase, you can also optionally specify `filters` block for limiting the amount\nof data that gets imported.\n\n```json\n{\n  \"dataSource\": {\n    \"filters\": {\n      \"companyId\": \"123\"\n    }\n  }\n}\n```\n\n**POST** `https://partners.zoined.com/api/customers`\n",
        "operationId": "partnerCreateCustomer",
        "tags": [
          "partner-customers"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "example": {
                "name": "Demo company",
                "key": "dm_company",
                "environment": "production",
                "locale": "en",
                "country": "FI",
                "currency": "EUR",
                "dateOffset": 0,
                "dataSource": {
                  "host": "db-host",
                  "port": 3306,
                  "database": "database_name",
                  "username": "db-username",
                  "password": "db-password"
                },
                "adminUser": {
                  "firstName": "My",
                  "lastName": "Name",
                  "email": "my.name@nonexisting.addr"
                },
                "licenses": [
                  "limited"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Customer creation has been accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateCustomerResponse"
                },
                "example": {
                  "key": "dm_company"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/customers/{id}": {
      "get": {
        "summary": "List single customer",
        "description": "List single customer matching provided identifier.\n\n**GET** `https://partners.zoined.com/api/customers/{id}`\n",
        "operationId": "partnerGetCustomer",
        "tags": [
          "partner-customers"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "id of customer",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "dm_company"
          }
        ],
        "responses": {
          "200": {
            "description": "Request has been processed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "No such customer exists in system."
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "patch": {
        "summary": "Edit customer",
        "description": "Change name, disabled state or data source configuration for customer.\n\n**PATCH** `https://partners.zoined.com/api/customers/{id}`\n",
        "operationId": "partnerUpdateCustomer",
        "tags": [
          "partner-customers"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "id of customer",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "dm_company"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Customer was updated successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "No such customer exists in system."
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "delete": {
        "summary": "Delete customer",
        "description": "Completely remove customer. This can only be done for customers who are not in the\nproduction state.\n\n**DELETE** `https://partners.zoined.com/api/customers/{id}`\n",
        "operationId": "partnerDeleteCustomer",
        "tags": [
          "partner-customers"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "id of customer",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "dm_company"
          }
        ],
        "responses": {
          "204": {
            "description": "When customer has been deleted successfully."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "No such customer exists in system."
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/customers/{id}/promote": {
      "post": {
        "summary": "Promote customer into production state",
        "description": "Promotes customer into production. Production customers have monitoring enabled,\nand their data can no longer be deleted via the API.\n\n**POST** `https://partners.zoined.com/api/customers/{id}/promote`\n",
        "operationId": "partnerPromoteCustomer",
        "tags": [
          "partner-customers"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "id of customer",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "dm_company"
          }
        ],
        "responses": {
          "200": {
            "description": "Customer was promoted successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "No such customer exists in system."
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/customers/{id}/data": {
      "delete": {
        "summary": "Truncate data",
        "description": "Removes all stored data from the customer. This is useful when setting up the customer\nintegration, if there are any issues with loading the data. Data can only be truncated\nwhen customer is still in sandbox mode. After user has been switched to production, data\ncan no longer be truncated with this API.\n\n**DELETE** `https://partners.zoined.com/api/customers/{id}/data`\n",
        "operationId": "partnerTruncateCustomerData",
        "tags": [
          "partner-customers"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "id of customer",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "dm_company"
          }
        ],
        "responses": {
          "204": {
            "description": "When opration completed successfully."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/customers/{id}/users": {
      "post": {
        "summary": "Invite users",
        "description": "Invite new users to specified customer.\n\n**POST** `https://partners.zoined.com/api/customers/{id}/users`\n",
        "operationId": "partnerInviteCustomerUser",
        "tags": [
          "partner-customers"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "id of customer",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "dm_company"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserInviteRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "When user has been invited successfully."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/customers/{id}/users/{user}": {
      "delete": {
        "summary": "Remove users",
        "description": "Remove specific user access from all roles for specified customer.\n\n**DELETE** `https://partners.zoined.com/api/customers/{id}/users/{user}`\n",
        "operationId": "partnerRemoveCustomerUser",
        "tags": [
          "partner-customers"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "id of customer",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "dm_company"
          },
          {
            "name": "user",
            "in": "path",
            "description": "email (user account id) of user to be removed",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "foo@example.com"
          }
        ],
        "responses": {
          "204": {
            "description": "When user roles have been removed successfully."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/messaging": {
      "post": {
        "summary": "Set new message",
        "description": "Adds new message to system as either broadcast or alternatively for specific customers. Replaces any existing message of that type.\n\n**POST** `https://partners.zoined.com/api/messaging`\n",
        "operationId": "partnerSetMessage",
        "tags": [
          "partner-messaging"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "customer",
            "in": "query",
            "description": "Optional customer IDs to apply the operation to specific partner companies only.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "example": [
              "company_a"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetMessageRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "When message has been deleted successfully."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "delete": {
        "summary": "Delete message",
        "description": "Remove either current broadcast message from system or alternatively messages for specific companies.\n\n**DELETE** `https://partners.zoined.com/api/messaging`\n",
        "operationId": "partnerDeleteMessage",
        "tags": [
          "partner-messaging"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "customer",
            "in": "query",
            "description": "Optional customer IDs to apply the operation to specific partner companies only.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "example": [
              "company_a"
            ]
          }
        ],
        "responses": {
          "204": {
            "description": "When message has been deleted successfully."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "get": {
        "summary": "Get message statistics",
        "description": "Returns information about either current broadcast message or customer specific message view statistics.\n\n**GET** `https://partners.zoined.com/api/messaging`\n",
        "operationId": "partnerGetMessageStatistics",
        "tags": [
          "partner-messaging"
        ],
        "servers": [
          {
            "url": "https://partners.zoined.com"
          }
        ],
        "security": [
          {
            "partnerToken": []
          }
        ],
        "parameters": [
          {
            "name": "customer",
            "in": "query",
            "description": "Optional customer IDs to apply the operation to specific partner companies only.",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "style": "form",
            "explode": true,
            "example": [
              "company_a"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "When request has been processed successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageStatus"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "No message exists in system."
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "partnerToken": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Use the Partner API token in this exact form:\n\n```\nAuthorization: Token token=\"your-token-here\"\n```\n"
      }
    },
    "responses": {
      "BadRequest": {
        "description": "When request has validation errors."
      },
      "Unauthorized": {
        "description": "When authentication fails."
      },
      "InternalServerError": {
        "description": "When internal service error has occurred."
      }
    },
    "schemas": {
      "SessionTransfer": {
        "x-tags": [
          "portal-data-structures"
        ],
        "type": "object",
        "description": "Decoded JSON structure that is Base64 encoded into the SSO payload.",
        "required": [
          "timestamp"
        ],
        "properties": {
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Current time in ISO 8601 format",
            "example": "2017-01-01T00:00:00Z"
          },
          "target_path": {
            "type": "string",
            "description": "Optional path in Zoined Portal where to redirect after sign in",
            "example": "/analytics/assortment_adhoc"
          },
          "user": {
            "$ref": "#/components/schemas/SessionTransferUserData"
          }
        }
      },
      "RestrictedDimensions": {
        "x-tags": [
          "portal-data-structures"
        ],
        "type": "object",
        "properties": {
          "store": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Array of store id's user can access. Empty array or nonexisting entry means no restrictions",
            "example": [
              "store1",
              "store2"
            ]
          }
        }
      },
      "UserRestrictions": {
        "x-tags": [
          "portal-data-structures"
        ],
        "type": "object",
        "properties": {
          "dimensions": {
            "$ref": "#/components/schemas/RestrictedDimensions"
          },
          "metrics": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Array of metric id's user can access. Empty array or nonexisting entry means no restrictions"
          }
        }
      },
      "SessionTransferUserData": {
        "x-tags": [
          "portal-data-structures"
        ],
        "type": "object",
        "required": [
          "first_name",
          "last_name",
          "email"
        ],
        "properties": {
          "first_name": {
            "type": "string",
            "description": "User's first name",
            "example": "John"
          },
          "last_name": {
            "type": "string",
            "description": "User's last name",
            "example": "Smith"
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "User's email",
            "example": "john.smith@email.email"
          },
          "language": {
            "type": "string",
            "description": "User's language. Empty or nonexisting entry means company default language.",
            "example": "en"
          },
          "role": {
            "type": "string",
            "enum": [
              "user",
              "admin"
            ],
            "description": "User's role in company",
            "example": "user"
          },
          "teams": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Array of team identifiers"
          },
          "restrictions": {
            "$ref": "#/components/schemas/UserRestrictions"
          }
        }
      },
      "DataSourceConfigurationBase": {
        "type": "object",
        "required": [
          "host",
          "port",
          "database",
          "username"
        ],
        "properties": {
          "host": {
            "type": "string",
            "description": "Database host",
            "example": "db-host"
          },
          "port": {
            "type": "number",
            "description": "Database port",
            "example": 3306
          },
          "database": {
            "type": "string",
            "description": "Database name",
            "example": "database_name"
          },
          "username": {
            "type": "string",
            "description": "Database username",
            "example": "db-username"
          }
        }
      },
      "DataSourceConfiguration": {
        "allOf": [
          {
            "$ref": "#/components/schemas/DataSourceConfigurationBase"
          },
          {
            "type": "object",
            "required": [
              "password"
            ],
            "properties": {
              "password": {
                "type": "string",
                "description": "Database password",
                "example": "db-password"
              }
            }
          }
        ]
      },
      "DataSourceConfigurationResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/DataSourceConfigurationBase"
          },
          {
            "type": "object",
            "required": [
              "password"
            ],
            "properties": {
              "password": {
                "type": "string",
                "description": "First three letters from the database password",
                "example": "db-XXXXXXXX"
              }
            }
          }
        ]
      },
      "DataUpdated": {
        "type": "object",
        "properties": {
          "visitors": {
            "type": "string",
            "format": "date-time",
            "example": "2016-03-22T13:02:36.000+02:00"
          }
        }
      },
      "CustomerResponse": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "Company's key",
            "example": "dm_company"
          },
          "name": {
            "type": "string",
            "description": "Company name",
            "example": "Demo company"
          },
          "createdAt": {
            "type": "string",
            "description": "12-10T12:12:30Z (string) - Customer creation time stamp",
            "example": "2019"
          },
          "disabled": {
            "type": "boolean",
            "description": "Customers's processing state. Disabled customers don't poll for new data",
            "example": false
          },
          "production": {
            "type": "boolean",
            "description": "Whether customer is in production mode",
            "example": true
          },
          "customerType": {
            "type": "string",
            "description": "Customer Type",
            "example": "other"
          },
          "token": {
            "type": "string",
            "description": "ZAPI access token for customer if applicable",
            "example": "abcdefghijklmn"
          },
          "status": {
            "type": "string",
            "description": "Status for the customer",
            "example": "ok"
          },
          "licenses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Customer product licenses",
            "example": [
              "standard"
            ]
          },
          "dataUpdated": {
            "$ref": "#/components/schemas/DataUpdated"
          },
          "dataSource": {
            "$ref": "#/components/schemas/DataSourceConfigurationResponse"
          },
          "ssoSecret": {
            "type": "string",
            "description": "SSO token if defined",
            "example": "asdajksdajdsjsdadjsasodaj"
          }
        }
      },
      "CustomerUpdateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Customer's name",
            "example": "New name"
          },
          "disabled": {
            "type": "boolean",
            "description": "Customer's processing state. Disabled customers don't poll for new data and customer users have no portal access nor receive emails.",
            "example": false
          },
          "dataSource": {
            "$ref": "#/components/schemas/DataSourceConfiguration"
          },
          "licenses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Array of customer product licenses",
            "example": [
              "limited"
            ]
          }
        }
      },
      "AdminUser": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "example": "My"
          },
          "lastName": {
            "type": "string",
            "example": "Name"
          },
          "email": {
            "type": "string",
            "format": "email",
            "example": "my.name@nonexisting.addr"
          }
        }
      },
      "CreateCustomerRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Demo company"
          },
          "key": {
            "type": "string",
            "description": "Optional customer key. If omitted, a key is created based on company name.",
            "example": "dm_company"
          },
          "environment": {
            "type": "string",
            "example": "production"
          },
          "locale": {
            "type": "string",
            "example": "en"
          },
          "country": {
            "type": "string",
            "example": "FI"
          },
          "currency": {
            "type": "string",
            "example": "EUR"
          },
          "dateOffset": {
            "type": "number",
            "example": 0
          },
          "dataSource": {
            "$ref": "#/components/schemas/DataSourceConfiguration"
          },
          "adminUser": {
            "$ref": "#/components/schemas/AdminUser"
          },
          "licenses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "limited"
            ]
          }
        }
      },
      "CreateCustomerResponse": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "example": "dm_company"
          },
          "token": {
            "type": "string",
            "description": "Returned for customers connected through ZAPI.",
            "example": "abcdefghijklmn"
          }
        }
      },
      "UserInviteRequest": {
        "type": "object",
        "required": [
          "email",
          "firstName",
          "lastName"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "description": "Email address for the user",
            "example": "john.smith@nonexisting.domain"
          },
          "firstName": {
            "type": "string",
            "description": "First name of the user",
            "example": "John"
          },
          "lastName": {
            "type": "string",
            "description": "Last name of the user",
            "example": "Smith"
          },
          "role": {
            "type": "string",
            "enum": [
              "user",
              "admin"
            ],
            "description": "Role of the user. Either user or admin.",
            "example": "user"
          }
        }
      },
      "SetMessageRequest": {
        "type": "object",
        "required": [
          "title",
          "message"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Message title. Only very basic formatting html allowed.",
            "example": "Important message"
          },
          "message": {
            "type": "string",
            "description": "Message content. Only very basic formatting html allowed.",
            "example": "Message content here"
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "description": "Date when to start showing the message",
            "example": "2020-01-01"
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "description": "Date when to stop showing the message.",
            "example": "2020-01-31"
          },
          "role": {
            "type": "string",
            "enum": [
              "user",
              "admin"
            ],
            "description": "Required role for users message is to be shown. Either user or admin.",
            "example": "user"
          }
        }
      },
      "MessageStatus": {
        "type": "object",
        "required": [
          "title",
          "message",
          "total_views",
          "customer_views"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Message title. Only very basic formatting html allowed.",
            "example": "Important message"
          },
          "message": {
            "type": "string",
            "description": "Message content. Only very basic formatting html allowed.",
            "example": "Message content here"
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "description": "Date when to start showing the message",
            "example": "2020-01-01"
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "description": "Date when to stop showing the message.",
            "example": "2020-01-31"
          },
          "role": {
            "type": "string",
            "enum": [
              "user",
              "admin"
            ],
            "description": "Required role for users message is to be shown. Either user or admin.",
            "example": "user"
          },
          "total_views": {
            "type": "number",
            "description": "Total number of views for all partner companies.",
            "example": 120
          },
          "customer_views": {
            "type": "object",
            "description": "Total views per customer."
          }
        }
      },
      "InvoicingCount": {
        "type": "object",
        "properties": {
          "cameras": {
            "type": "integer",
            "example": 19
          },
          "registers": {
            "type": "integer",
            "example": 12
          },
          "stores": {
            "type": "integer",
            "example": 3
          }
        }
      },
      "InvoicingCustomerCount": {
        "type": "object",
        "properties": {
          "customer": {
            "type": "string",
            "example": "dm_company"
          },
          "cameras": {
            "type": "integer",
            "example": 14
          },
          "registers": {
            "type": "integer",
            "example": 10
          },
          "stores": {
            "type": "integer",
            "example": 2
          }
        }
      },
      "InvoicingPeriod": {
        "type": "object",
        "properties": {
          "customers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvoicingCustomerCount"
            }
          },
          "date": {
            "type": "string",
            "description": "Month in YYYY-MM format.",
            "example": "2016-01"
          },
          "total": {
            "$ref": "#/components/schemas/InvoicingCount"
          }
        }
      },
      "InvoicingResponse": {
        "type": "object",
        "properties": {
          "customers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "dm_company",
              "dm_company2"
            ]
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvoicingPeriod"
            }
          }
        }
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "Zone - Zoined Partner API",
      "tags": [
        "partner-overview",
        "partner-maintenance",
        "partner-customers",
        "partner-messaging"
      ]
    },
    {
      "name": "Zoined Retail Analytics Portal API",
      "tags": [
        "portal-overview",
        "portal-session-transfer",
        "portal-data-structures"
      ]
    }
  ]
}