openapi: 3.0.2
info:
  title: API pública de parceiros TiqueTaque
  version: '1'
  description: |
    <h2>Autenticação</h2>
      Para todas as requisições, exceto a geração de token, é necessária a autenticação com um token JWT
      de parceiro, enviado no header <code>Authorization: Bearer &ltseu_token&gt</code>.<br>
      O token é obtido através do endpoint <code>POST /tokens</code> desta API, utilizando as credenciais
      de um usuário do portal de parceiros. A resposta contém o campo <code>token</code> a ser usado
      nas requisições.
    <h2>Rate limiting</h2>
      Requisições são limitadas a 60 requisições por janela deslizante de 1 minuto.
      Se o limite for excedido, será retornada uma resposta HTTP <code>429 Too Many Requests</code>.<br>
security:
  - BearerAuth: []
servers:
  - url: https://api.tiquetaque.com/partners/v1
    description: Production
tags:
  - name: Autenticação
    description: Geração de token de acesso à API de parceiros.
  - name: Contas
    description: Operações sobre as contas criadas pelo parceiro.
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    IsoDateTimeTzModel:
      type: string
      pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-][0-2]\d:[0-5]\d$
      example: '2026-01-01T00:00:00+00:00'
    PartnerAccountModel:
      type: object
      properties:
        _id:
          description: Identificador único da conta, gerado internamente.
          type: string
          example: 5f5bc225b511a6edec2891f7
        _created:
          $ref: '#/components/schemas/IsoDateTimeTzModel'
        name:
          description: Nome do empregador vinculado à conta.
          type: string
          nullable: true
          example: TIQUETAQUE SERVICOS DE TECNOLOGIA S.A.
        financial_email:
          description: E-mail do setor financeiro do empregador vinculado à conta.
          type: string
          nullable: true
          example: financeiro@empresa.com
        cnpj:
          description: CNPJ do empregador vinculado à conta. Apenas números.
          type: string
          nullable: true
          example: '23467093000164'
        active_employees:
          description: Número de funcionários ativos da conta.
          type: integer
          example: 12
        subscription_employees:
          description: Número de funcionários contratados nas assinaturas da conta.
          type: integer
          example: 15
        subscription_face_ids:
          description: >-
            Número de reconhecimentos faciais contratados na assinatura ativa da
            conta.
          type: integer
          example: 5
    PartnerAccountDetailModel:
      allOf:
        - $ref: '#/components/schemas/PartnerAccountModel'
        - type: object
          properties:
            api_token:
              description: >
                Token de acesso da conta à API pública TiqueTaque (usado com
                autenticação BasicAuth sendo user=public,
                senha=&ltapi_token&gt). Presente somente quando o header
                <code>X-Secret</code> da requisição corresponde à chave secreta
                da conta (campo <code>secret</code> retornado na criação da
                conta); caso o header esteja ausente ou não corresponda, o campo
                não é retornado. Retorna null caso o token tenha sido revogado.
              type: string
              nullable: true
              example: 8f14e45fceea167a5a36dedd4bea2543
    PartnerTokenRequestModel:
      type: object
      required:
        - email
        - password
      properties:
        email:
          description: E-mail do usuário do portal de parceiros.
          type: string
          example: parceiro@empresa.com
        password:
          description: Senha do usuário do portal de parceiros.
          type: string
    PartnerTokenModel:
      type: object
      properties:
        token:
          description: >-
            Token JWT de parceiro a ser usado no header Authorization das demais
            requisições.
          type: string
        _id:
          description: Identificador único do usuário do portal de parceiros autenticado.
          type: string
          example: 5f5bc225b511a6edec2891f7
    PartnerAccountPostModel:
      type: object
      required:
        - full_name
        - email
        - mobile_phone
        - company_doc
        - employees_quantity
      properties:
        full_name:
          description: Nome completo do usuário administrador da nova conta.
          type: string
          maxLength: 200
          example: Exemplo da Silva
        employees_quantity:
          description: >-
            Quantidade de funcionários da assinatura da nova conta. Deve ser
            entre 1 e 5000.
          type: integer
          minimum: 1
          maximum: 5000
          example: 10
        email:
          description: >-
            E-mail do usuário administrador da nova conta. Recebe os e-mails de
            ativação e boas-vindas.
          type: string
          example: exemplo@empresa.com
        mobile_phone:
          description: Número de telefone celular com código de área, somente números.
          type: string
          example: '11991234567'
        company_doc:
          type: object
          required:
            - name
            - trade_name
            - address
          properties:
            name:
              description: Razão social do empregador.
              type: string
              example: TIQUETAQUE SERVICOS DE TECNOLOGIA S.A.
            trade_name:
              description: Nome fantasia do empregador.
              type: string
              example: TiqueTaque
            cpf:
              description: >
                CPF do empregador. Apenas números. Necessário que exista ou este
                campo ou o campo CNPJ, mutuamente exclusivos.
              type: string
              pattern: ^\d{11}$
              example: '01234567890'
            cnpj:
              description: >
                CNPJ do empregador. Apenas números. Necessário que exista ou
                este campo ou o campo CPF, mutuamente exclusivos.
              type: string
              pattern: ^[0-9A-Z]{12}\d{2}$
              example: '23467093000164'
            financial_email:
              description: E-mail do setor financeiro do empregador.
              type: string
              example: financeiro@empresa.com
            address:
              type: object
              required:
                - cep
                - street_name
                - street_number
                - neighborhood
                - state
                - city
              properties:
                cep:
                  description: CEP do endereço do empregador. Apenas números.
                  type: string
                  example: '90240111'
                street_name:
                  description: Logradouro do endereço.
                  type: string
                  example: RUA FREDERICO MENTZ
                street_number:
                  description: Número do endereço.
                  type: string
                  maxLength: 6
                  example: '1606'
                neighborhood:
                  description: Bairro do endereço.
                  type: string
                  example: Navegantes
                complement:
                  description: Complemento do endereço, caso exista.
                  type: string
                  example: LOJA 134
                state:
                  description: UF do endereço.
                  type: string
                  example: RS
                city:
                  description: Cidade do endereço do empregador.
                  type: string
                  example: Porto Alegre
    LinksModel:
      type: object
      properties:
        parent:
          type: object
          properties:
            href:
              type: string
            title:
              type: string
        self:
          description: Página atual. Presente apenas quando existem resultados.
          type: object
          properties:
            href:
              type: string
            title:
              type: string
        next:
          description: Próxima página. Presente apenas quando existe uma página seguinte.
          type: object
          properties:
            href:
              type: string
            title:
              type: string
        last:
          description: Última página. Presente apenas quando existe mais de uma página.
          type: object
          properties:
            href:
              type: string
            title:
              type: string
    MetaModel:
      type: object
      properties:
        max_results:
          type: integer
        page:
          type: integer
        total:
          type: integer
    MaxResultsParamModel:
      type: integer
      description: Tamanho da página dos resultados, valor padrão 25.
      default: 25
    PageParamModel:
      type: integer
      description: Número da página de resultados solicitada.
      default: 1
    ErroRespostaModel:
      description: Resposta de erro
      type: object
      properties:
        _code:
          description: >
            Código de erro interno. Ausente nos erros de validação de campos,
            nos quais <code>_error.message</code> contém um objeto com os erros
            por campo.
          type: integer
        _status:
          type: string
          example: ERR
        _error:
          type: object
          properties:
            code:
              description: Codigo de erro HTTP.
              type: integer
            message:
              description: >
                Mensagem de erro interna. Nos erros de validação de campos (veja
                <code>_code</code>), é um objeto que mapeia cada campo inválido
                à lista de mensagens de erro daquele campo.
              oneOf:
                - type: string
                - type: object
                  additionalProperties:
                    type: array
                    items:
                      type: string
            ui_message:
              description: Mensagem de erro para o usuário.
              type: string
  examples:
    401_example:
      value:
        _code: 9
        _error:
          code: 401
          message: Invalid account credentials.
          ui_message: Credenciais inválidas
        _status: ERR
    403_example:
      value:
        _code: 666
        _error:
          code: 403
          message: Forbidden resource for this token.
          ui_message: Acesso não autorizado.
        _status: ERR
    404_account_example:
      value:
        _code: 56
        _error:
          code: 404
          message: account not found.
          ui_message: account não encontrado.
        _status: ERR
    422_validation_example:
      summary: Erro de validação de campos
      value:
        _error:
          code: 422
          message:
            company_doc:
              - required field
        _status: ERR
    422_invalid_account_id_example:
      summary: Identificador da conta com formato inválido
      value:
        _code: 113
        _error:
          code: 422
          message: Invalid 'account_id' query parameter for request.
          ui_message: Parâmetro account_id inválido para essa requisição.
        _status: ERR
    422_invalid_body_example:
      summary: Corpo da requisição não é um JSON válido
      value:
        _code: 1405
        _error:
          code: 422
          message: Invalid body format.
          ui_message: Formato do corpo da requisição inválido.
        _status: ERR
    422_duplicated_email_example:
      summary: E-mail já cadastrado
      value:
        _code: 88
        _error:
          code: 422
          message: Value is not unique
          ui_message: Valor já cadastrado no sistema.
        _status: ERR
paths:
  /tokens:
    post:
      operationId: postPartnerToken
      tags:
        - Autenticação
      summary: Gera um token de parceiro
      description: >
        Gera um token JWT de parceiro a partir das credenciais de um usuário do
        portal de parceiros. O token retornado deve ser enviado no header
        <code>Authorization: Bearer &lttoken&gt</code> das demais requisições
        desta API.
      security: []
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerTokenRequestModel'
      responses:
        '200':
          description: Token gerado com sucesso.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerTokenModel'
        '401':
          description: >
            Erro por credenciais ausentes ou inválidas, ou por usuário ainda não
            ativado. Usuários do portal de parceiros precisam ativar a conta
            pelo link recebido por e-mail antes do primeiro login.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                credenciais_invalidas:
                  summary: Credenciais ausentes ou inválidas
                  value:
                    _code: 1418
                    _error:
                      code: 401
                      message: Invalid credentials.
                      ui_message: Credenciais inválidas.
                    _status: ERR
                usuario_nao_ativado:
                  summary: Usuário ainda não ativado
                  value:
                    _code: 24
                    _error:
                      code: 401
                      message: Account not activated. Verify email.
                      ui_message: Conta ainda não ativada, verifique o e-mail de ativação.
                    _status: ERR
        '422':
          description: Erro por corpo da requisição inválido.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                corpo_invalido:
                  $ref: '#/components/examples/422_invalid_body_example'
  /partner-accounts:
    get:
      operationId: getPartnerAccounts
      tags:
        - Contas
      summary: Lista as contas criadas pelo parceiro
      description: >
        Retorna a listagem paginada das contas vinculadas ao parceiro
        identificado pelo token da requisição, ordenadas da mais recente para a
        mais antiga. Cada conta é retornada com o nome, e-mail financeiro e CNPJ
        do empregador, o número de funcionários ativos, o número de funcionários
        contratados na assinatura e o número de reconhecimentos faciais
        contratados na assinatura ativa.<br><br> A listagem nunca retorna o
        token de acesso das contas à API pública TiqueTaque; ele pode ser obtido
        através do endpoint <code>GET /partner-accounts/{account_id}</code>,
        mediante a chave secreta da conta.
      parameters:
        - name: max_results
          description: Tamanho da página de resultados paginados.
          required: false
          in: query
          schema:
            $ref: '#/components/schemas/MaxResultsParamModel'
        - name: page
          description: Número da página de resultados a retornar
          required: false
          in: query
          schema:
            $ref: '#/components/schemas/PageParamModel'
      responses:
        '200':
          description: Lista de contas do parceiro.
          content:
            application/json:
              schema:
                type: object
                properties:
                  _items:
                    type: array
                    items:
                      $ref: '#/components/schemas/PartnerAccountModel'
                  _links:
                    $ref: '#/components/schemas/LinksModel'
                  _meta:
                    $ref: '#/components/schemas/MetaModel'
        '401':
          description: Erro por credenciais ausentes ou inválidas.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                '401':
                  $ref: '#/components/examples/401_example'
        '403':
          description: Erro por token sem permissão de acesso ao recurso.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                '403':
                  $ref: '#/components/examples/403_example'
    post:
      operationId: postPartnerAccount
      tags:
        - Contas
      summary: Cria uma nova conta vinculada ao parceiro
      description: >
        Cria uma nova conta vinculada ao parceiro identificado pelo token da
        requisição, aplicando o cupom do parceiro quando este possui um, junto
        com uma assinatura com a quantidade de funcionários informada em
        <code>employees_quantity</code> (entre 1 e 5000). São criados os
        cadastros iniciais da conta: o usuário administrador, o empregador, a
        unidade e uma escala de trabalho de exemplo. Os e-mails de ativação e
        boas-vindas são enviados ao usuário administrador quando a assinatura da
        conta é ativada.<br><br> A conta é criada com seu token de acesso à API
        pública TiqueTaque e a chave secreta já gerados, retornados nos campos
        <code>api_token</code> e <code>secret</code> da resposta. A chave
        secreta é retornada somente nesta resposta e não pode ser consultada
        posteriormente.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerAccountPostModel'
      responses:
        '200':
          description: Conta criada com sucesso.
          content:
            application/json:
              schema:
                type: object
                properties:
                  _id:
                    description: Identificador único da nova conta.
                    type: string
                    example: 5f5bc225b511a6edec2891f7
                  api_token:
                    description: >
                      Token de acesso da nova conta à API pública TiqueTaque
                      (usado com autenticação BasicAuth sendo user=public,
                      senha=&ltapi_token&gt), gerado automaticamente na criação
                      da conta.
                    type: string
                    nullable: true
                    example: e7a56a3e-8a5b-4a75-b7a4-4bfbe6f36a10
                  secret:
                    description: >
                      Chave secreta da nova conta, gerada automaticamente na
                      criação. Retornada somente nesta resposta, não sendo
                      possível consultá-la posteriormente.
                    type: string
                    nullable: true
                    example: kHc9tGm3xQ7LpZ2vNwRbQg
        '401':
          description: Erro por credenciais ausentes ou inválidas.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                '401':
                  $ref: '#/components/examples/401_example'
        '403':
          description: Erro por token sem permissão de acesso ao recurso.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                '403':
                  $ref: '#/components/examples/403_example'
        '422':
          description: >
            Parâmetro obrigatório ausente ou com formato inválido, corpo da
            requisição inválido, ou e-mail do usuário administrador já
            cadastrado.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                erro_validacao:
                  $ref: '#/components/examples/422_validation_example'
                corpo_invalido:
                  $ref: '#/components/examples/422_invalid_body_example'
                email_duplicado:
                  $ref: '#/components/examples/422_duplicated_email_example'
  /partner-accounts/{account_id}:
    get:
      operationId: getPartnerAccount
      tags:
        - Contas
      summary: Retorna uma conta criada pelo parceiro
      description: >
        Retorna uma conta vinculada ao parceiro identificado pelo token da
        requisição, com os mesmos campos da listagem de contas e o campo
        <code>api_token</code>. A conta pode ser identificada pelo seu
        identificador único (campo <code>_id</code>) ou pelo documento do
        empregador: CNPJ (incluindo o novo formato alfanumérico) ou CPF, sem
        pontuação.<br><br> O token de acesso da conta à API pública TiqueTaque
        (<code>api_token</code>) é retornado somente quando o header
        <code>X-Secret</code> da requisição corresponde à chave secreta da
        conta; caso contrário o campo não é retornado. A chave secreta é exibida
        somente no momento da criação  de cada conta.
      parameters:
        - name: account_id
          description: >
            Identificador único da conta (campo <code>_id</code>, 24 caracteres
            hexadecimais), CNPJ do empregador da conta (14 caracteres sem
            pontuação: 12 letras ou dígitos mais 2 dígitos verificadores,
            aceitando o novo formato alfanumérico, com letras maiúsculas ou
            minúsculas) ou CPF do empregador da conta (11 dígitos, sem
            pontuação).<br><br> Os documentos são procurados somente entre os
            empregadores das contas do parceiro e seus dígitos verificadores não
            são validados: um CNPJ ou CPF com formato válido que não corresponda
            a nenhuma conta do parceiro retorna <code>404</code>. Documentos com
            pontuação ou qualquer outro formato retornam <code>422</code>.
          required: true
          in: path
          schema:
            type: string
            pattern: ^([0-9a-fA-F]{24}|[0-9A-Za-z]{12}[0-9]{2}|[0-9]{11})$
          examples:
            id:
              summary: Identificador único da conta
              value: 5f5bc225b511a6edec2891f7
            cnpj:
              summary: CNPJ do empregador
              value: '23467093000164'
            cnpj_alfanumerico:
              summary: CNPJ alfanumérico do empregador
              value: 12ABC34501DE35
            cpf:
              summary: CPF do empregador
              value: '01234567890'
        - name: X-Secret
          description: >
            Chave secreta da conta (campo <code>secret</code> retornado na
            criação da conta). Quando presente e correspondente à chave secreta
            da conta, o campo <code>api_token</code> é retornado com o token de
            acesso à API pública.
          required: false
          in: header
          schema:
            type: string
      responses:
        '200':
          description: Conta do parceiro.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerAccountDetailModel'
        '401':
          description: Erro por credenciais ausentes ou inválidas.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                '401':
                  $ref: '#/components/examples/401_example'
        '403':
          description: Erro por token sem permissão de acesso ao recurso.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                '403':
                  $ref: '#/components/examples/403_example'
        '404':
          description: >
            Erro por conta inexistente, não vinculada ao parceiro ou sem
            empregador com o CNPJ ou CPF informado.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                '404':
                  $ref: '#/components/examples/404_account_example'
        '422':
          description: >
            Erro por identificador com formato inválido: <code>account_id</code>
            deve ser o identificador único da conta (24 caracteres
            hexadecimais), o CNPJ do empregador (14 caracteres, sem pontuação)
            ou o CPF do empregador (11 dígitos, sem pontuação). Documentos
            enviados com pontuação também retornam este erro.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErroRespostaModel'
              examples:
                identificador_invalido:
                  $ref: '#/components/examples/422_invalid_account_id_example'
