{
  "openapi": "3.1.0",
  "info": {
    "title": "Traculo API v1 (read operations)",
    "version": "1.0.0",
    "description": "Read your Traculo web analytics: your websites, tracked events, a summary of visitors and top pages and sources, and flat report rows. Authenticate with an API token (Account settings, API tokens in Traculo; a Read only token is enough). Timestamps in events are database time, YYYY-MM-DD HH:MM:SS.",
    "contact": {
      "email": "support@traculo.com",
      "url": "https://traculo.com/contact-us/"
    },
    "externalDocs": {
      "description": "Full API documentation",
      "url": "https://app.traculo.com/docs/api"
    }
  },
  "servers": [
    {
      "url": "https://api.traculo.com"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/me": {
      "get": {
        "operationId": "getMe",
        "summary": "The account the token belongs to",
        "description": "Returns the id, e-mail and name of the account that owns the API token.",
        "parameters": [],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is {\"data\": ...}.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired token."
          },
          "403": {
            "description": "The token or the user has no access to this website."
          },
          "429": {
            "description": "More than 60 requests a minute for this token. See the Retry-After header."
          }
        }
      }
    },
    "/v1/domains": {
      "get": {
        "operationId": "listWebsites",
        "summary": "List the websites the token can use",
        "description": "Returns the websites of the account that the token allows. Not paged.",
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Keep only websites whose name contains this text (case-insensitive).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is {\"data\": ...}.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebsitesResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired token."
          },
          "403": {
            "description": "The token or the user has no access to this website."
          },
          "429": {
            "description": "More than 60 requests a minute for this token. See the Retry-After header."
          }
        }
      }
    },
    "/v1/domains/{id}/events": {
      "get": {
        "operationId": "listEvents",
        "summary": "List tracked events of a website",
        "description": "The latest tracked events of a website, newest first, with their properties.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The numeric id of the website, from GET /v1/domains.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Events per response. Default 50, at most 200.",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Events to skip, for paging. Default 0.",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "First day, YYYY-MM-DD, included.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Last day, YYYY-MM-DD, included.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "description": "Only events with exactly this name, for example order_complete.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is {\"data\": ...}.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired token."
          },
          "403": {
            "description": "The token or the user has no access to this website."
          },
          "429": {
            "description": "More than 60 requests a minute for this token. See the Retry-After header."
          }
        }
      }
    },
    "/v1/domains/{id}/summary": {
      "get": {
        "operationId": "getSummary",
        "summary": "Visitors, visits, page views, top pages and top sources",
        "description": "Headline numbers for the last complete days, ending yesterday, with the 10 biggest pages and sources.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The numeric id of the website, from GET /v1/domains.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "The number of days: 7 (default) or 30.",
            "schema": {
              "type": "integer",
              "enum": [
                7,
                30
              ],
              "default": 7
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is {\"data\": ...}.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SummaryResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired token."
          },
          "403": {
            "description": "The token or the user has no access to this website."
          },
          "429": {
            "description": "More than 60 requests a minute for this token. See the Retry-After header."
          }
        }
      }
    },
    "/v1/domains/{id}/report": {
      "get": {
        "operationId": "getReport",
        "summary": "Flat report rows for any metric and dimension",
        "description": "Tabular rows (columns follow the order asked: dimensions, then metrics). Use it for any breakdown that summary does not cover. The range is at most 366 days, and 31 days when date is combined with another dimension.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The numeric id of the website, from GET /v1/domains.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "metrics",
            "in": "query",
            "required": true,
            "description": "Comma separated, 1 to 10 of: page_views, visitors, sessions, conversions, bounce_rate, avg_visit_duration.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dimensions",
            "in": "query",
            "required": false,
            "description": "Comma separated, at most 2: date, page_path, entry_page, exit_page, channel, source, medium, campaign, utm_source, utm_campaign, utm_content, utm_term, country, region, city, device_type, browser, os, event_name. Not every metric fits every dimension.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "description": "First day, YYYY-MM-DD, included.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "description": "Last day, YYYY-MM-DD, included. Not in the future.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Rows per response. Default 10000, at most 100000.",
            "schema": {
              "type": "integer",
              "default": 10000,
              "maximum": 100000
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Rows to skip, for paging. Use next_offset from the previous response.",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The body is {\"data\": ...}.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, revoked or expired token."
          },
          "403": {
            "description": "The token or the user has no access to this website."
          },
          "429": {
            "description": "More than 60 requests a minute for this token. See the Retry-After header."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "A Traculo API token that starts with trc_."
      }
    },
    "schemas": {
      "MeResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "user": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "integer"
                  },
                  "email": {
                    "type": "string"
                  },
                  "name": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        }
      },
      "WebsitesResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "domains": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer"
                    },
                    "domain": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "EventsResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "events": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "integer"
                    },
                    "name": {
                      "type": "string"
                    },
                    "created_at": {
                      "type": "string",
                      "description": "Database time, YYYY-MM-DD HH:MM:SS."
                    },
                    "properties": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  }
                }
              },
              "total": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              },
              "offset": {
                "type": "integer"
              }
            }
          }
        }
      },
      "SummaryResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "range": {
                "type": "object",
                "properties": {
                  "days": {
                    "type": "integer"
                  },
                  "from": {
                    "type": "string",
                    "format": "date"
                  },
                  "to": {
                    "type": "string",
                    "format": "date"
                  }
                }
              },
              "visitors": {
                "type": "integer"
              },
              "visits": {
                "type": "integer"
              },
              "page_views": {
                "type": "integer"
              },
              "top_pages": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "views": {
                      "type": "integer"
                    }
                  }
                }
              },
              "top_sources": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "source": {
                      "type": "string"
                    },
                    "visits": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "ReportResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    },
                    "role": {
                      "type": "string",
                      "enum": [
                        "dimension",
                        "metric"
                      ]
                    }
                  }
                }
              },
              "rows": {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {}
                }
              },
              "range": {
                "type": "object",
                "properties": {
                  "from": {
                    "type": "string",
                    "format": "date"
                  },
                  "to": {
                    "type": "string",
                    "format": "date"
                  }
                }
              },
              "total": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              },
              "offset": {
                "type": "integer"
              },
              "has_more": {
                "type": "boolean"
              },
              "next_offset": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          }
        }
      }
    }
  }
}
