# QI Tech — Risk Solutions › Antifraude de Aluguel de Carros

Documentação da QI Tech em texto corrido, para colar em um LLM.
Fonte: https://docs.qitech.com.br
12 página(s).

Índice:
- Status HTTP (/documentation/caas/car_rental/http_status)
- Imagens (/documentation/caas/car_rental/image)
- Introdução (/documentation/caas/car_rental/introduction)
- Troca de Mensagens (/documentation/caas/car_rental/messages)
- Objetos Compartilhados (/documentation/caas/car_rental/objects)
- Envio de Resultado Quiz (/documentation/caas/car_rental/quiz)
- RentalAgreement-v1 (/documentation/caas/car_rental/rental_agreement)
- RentalAgreement-v2 (/documentation/caas/car_rental/rental_agreement_v2)
- Reservation-v1 (/documentation/caas/car_rental/reservation)
- Reservation-v2 (/documentation/caas/car_rental/reservation_v2)
- Padrões (/documentation/caas/car_rental/standards)
- Webhook (/documentation/caas/car_rental/webhook)

---

# Status HTTP

URL: /documentation/caas/car_rental/http_status

Todas as APIs da QI Tech utilizam a seguinte padronização nos status HTTP de retorno, de acordo com o [RFC 7231](https://tools.ietf.org/html/rfc7231):

| Status HTTP | Significado | Descrição |
| ---------- | ------- | --------------------------------- |
| 400 | Bad Request | A requisição enviada possui algum erro de formatação. Na maioria dos casos, retornamos no corpo da mensagem uma explicação de onde está o erro. |
| 401 | Unauthorized | Houve algum problema na autenticação, verifique se a API Key está correta e no header correto, de acordo com a seção Autenticação. |
| 403 | Forbidden | O endpoint acessado é de uso interno e não está disponível para esta API Key. |
| 404 | Not Found | O dado requisitado não foi encontrado usando a chave utilizada. Este status também é retornado quando um endpoint inválido é requisitado. |
| 405 | Method Not Allowed | O método HTTP utilizado não se aplica ao endpoint utilizado. |
| 406 | Not Acceptable | Os dados enviados no corpo da requisição são inválidos. Em geral, isso significa que os dados enviados não são um JSON válido. |
| 409 | Conflict | O id da requisição corresponde a um id já processado anteriormente. Este status é retornado no caso de requisições duplicadas enviadas ao servidor. |
| 500 | Internal Server Error | Tivemos um problema para processar esta requisição, ao encontrarmos esse erro nossos especialistas são automaticamente notificados e iniciam a análise e solução imediatamente. |
| 503 | Service Unavailable | Você se deparou com uma indisponibilidade, planejada ou não, de infraestrutura dos nossos servidores. |

---

# Imagens

URL: /documentation/caas/car_rental/image

Em várias situações é necessário enviar imagens para a nossa API, a fim de realizar operações de OCR, FaceMatch e validação de documentos. Para tanto, é preciso inicialmente realizar o upload da imagem para depois enviá-la para análise.

Ao enviar uma imagem utilizando o endpoint /image uma GUID (Globally Unique Identifier) é retornada. Este valor deverá ser utilizado nas chamadas subsequentes para referenciar esta imagem.

:::warning
O tamanho máximo de uma imagem aceita é de 10MB.
:::

:::warning
Neste momento, somente imagens com formato jpg são aceitas.
:::

## Envio

Exemplo de envio utilizando o cUrl:

```shell
curl -F "data=@path/to/local/file" \
     -H "Authorization: TESTETESTETESTE" \
     -H "DocumentNumber: 000.000.000-00" \
     "https://api.caas.qitech.app/car_rental/image?type=face"
```

Exemplo de retorno:

```json
{
  "image_key": "f1c0d2e1-f950-4360-896d-36588e443fc9",
  "file_name": "05696664903.jpg",
  "file_size": 47407,
  "width_px": 0,
  "height_px": 0,
  "type": "face",
  "created_at": "2020-07-29T18:40:57Z"
}
```

Para enviar uma imagem, basta realizar o envio da imagem no formato .jpg em `multipart/form-data` com uma requisição POST no endpoint:

`POST https://api.caas.qitech.app/car_rental/image?type=$type`

Onde $type é a classificação da imagem e deve ser enviado conforme um dos seguintes enumeradores (Caso a imagem sendo enviada não se enquadre em nenhuma das classificações, entrar em contato com o [suporte](mailto:suporte.caas@qitech.com.br) para que providenciem a adição):

- `face`
- `driver_license`
- `id`
- `contract`

Após o envio, será retornado um objeto JSON com a GUID que aponta para a imagem que foi enviada.

## Análise da Imagem para App

Ao utilizar a api_key do App, o resultado contará com um valor adicional, chamado de `result` que pode receber os seguintes valores:

- `registration_approved`
- `registration_reproved`

Que indica se o cadastro da foto foi aprovado ou reprovado.

Neste momento, a qualidade da foto também é avaliada, podendo receber um resultado 400, conforme descrito no próximo item.

Exemplo de retorno para o App:

```json
{
  "image_key": "f1c0d2e1-f950-4360-896d-36588e443fc9",
  "file_name": "05696664903.jpg",
  "file_size": 47407,
  "width_px": 0,
  "height_px": 0,
  "type": "face",
  "result": "registration_approved",
  "created_at": "2020-07-29T18:40:57Z"
}
```

## Validação de qualidade da imagem

Exemplo de retorno em caso de imagem inválida:

```json
{
  "title": "image_quality",
  "description": "A imagem enviada não possui uma face"
}
```

Ao realizar um post no endpoint de imagem, caso a imagem não seja suficiente para validação, um HTTP Status Code 400 será retornado, como pode ser visto no exemplo acima.

O valor do campo description é a mensagem que explica o motivo da imagem ser inválida.

:::info
Existem outros motivos pelos quais retornaremos 400 (Todos relacionados a dados inválidos). Somente os retornos com title "image_quality" são resultantes da validação de qualidade da imagem e portanto devem ser repassados ao usuário.
:::

## Recuperação dos Arquivos

Leitura de imagem:

```shell
curl "https://api.caas.qitech.app/car_rental/image/{image_key}/file" \
     -H "Authorization: TESTETESTETESTE"
```

Após o envio de uma imagem para a API, é possível recuperá-la por meio de uma requisição GET adequadamente autenticada no endpoint:

`GET https://api.caas.qitech.app/car_rental/image/{image_key}/file`

Onde image_key é o valor retornado durante o envio da imagem.

## Recuperação dos meta-dados do arquivo

Leitura de meta dados:

```shell
curl "https://api.caas.qitech.app/car_rental/image/{image_key}" \
     -H "Authorization: TESTETESTETESTE"
```

Após o envio de uma imagem para a API, é possível recuperar os meta-dados da imagem utilizando o endpoint:

`GET https://api.caas.qitech.app/car_rental/image/{image_key}`

Onde image_key é o valor retornado durante o envio da imagem.

---

# Introdução

URL: /documentation/caas/car_rental/introduction

Bem vindo à API de Prevenção a Fraudes em aluguel de veículos da QI Tech! Você pode utilizar a nossa API para acessar os endpoints, a fim de receber a resposta de um contrato de aluguel, além de utilizar para atualizar a situação de um contrato.

## Problemas?

Nós não somos uma companhia que se esconde atrás de uma API! Entre em contato com o nosso [suporte](mailto:suporte.caas@qitech.com.br) e nós responderemos o mais rápido possível. Fique à vontade para nos ligar caso deseje uma resposta rápida!

### Adoramos Feedback

Mesmo que você já tenha resolvido o seu problema ou que ele seja muito simples (Até mesmo um typo ou uma organização inadequada que você já entendeu), envie-nos um e-mail, assim nós tornamos a documentação cada vez mais prática e a próxima pessoa não vai precisar sofrer as dores que você sofreu!

## Ambientes

Possuímos dois ambientes para os nossos clientes. A URL base das APIs são:

- Produção - `https://api.caas.qitech.app/car_rental/`
- Sandbox - `https://api.sandbox.caas.qitech.app/car_rental/`

No ambiente de Sandbox, as análises enviadas não são cobradas e são respondidas de acordo com a seguinte regra **baseada no valor total do aluguel**:

| Mínimo | Máximo | Decisão |
| ------ | ------ | ------- |
| 10000 | -- | Pendente (Em análise Manual) - Sem Decisão da Mesa |
| 8000 | 9999 | Aprovado Automaticamente |
| 6000 | 7999 | Reprovado Automaticamente |
| 5000 | 5999 | Derivado para Análise Manual - Com aprovação posterior |
| 4000 | 4999 | Derivado para Análise Manual - Com reprovação posterior |
| 3000 | 3999 | Derivado para Análise Manual - Com Desafio Manual |
| 0 | 2999 | Pendente (Em análise Manual) - Sem Decisão da Mesa |

As análises de upgrade em ambiente de Sandbox seguirão as decisões de análise abaixo:

| Grupos | upgrade_status |
| ------ | -------------- |
| ('C', 'CX', 'SV', 'SU') | 'automatically_approved' |
| ('IE', 'J', 'SG') | 'automatically_reproved' |

## Somente HTTPS

Por questão de segurança, toda a comunicação com as APIs da QI Tech devem ser realizadas utilizando a comunicação HTTPS. Para garantir que, por desatenção ou qualquer outro motivo, não ocorram chamadas HTTP, este servidor somente disponibiliza a porta 443 com comunicação TLS 1.2. Chamadas realizadas utilizando outros protocolos serão automaticamente negadas.

## Autenticação

```shell
# No shell, você somente precisa adicionar o header adequado em cada requisição
curl "api_endpoint_here"
  -H "Authorization: API-KEY-EXAMPLE"
```

:::info
Substitua a API key `API-KEY-EXAMPLE` com a sua chave adquirida com o nosso suporte.
:::

Utilizamos uma API Key para permitir acesso a nossa API. Ela provavelmente já foi enviada por e-mail para você. Caso você ainda não tenha recebido a sua chave, envie um e-mail para [suporte.caas@qitech.com.br](mailto:suporte.caas@qitech.com.br).

Nossa API espera receber a API Key em todas as requisições ao nosso servidor em um header como o abaixo:

`Authorization: API-KEY-EXAMPLE`

:::note
Você deve substituir `API-KEY-EXAMPLE` com a API Key recebida do suporte.
:::

---

# Troca de Mensagens

URL: /documentation/caas/car_rental/messages

Para a troca de mensagens entre a mesa de análise manual e o atendente da loja, são disponibilizados dois endpoints:

- `POST https://api.caas.qitech.app/car_rental/rental_agreement/{rental_agreement_id}/message`
- `GET https://api.caas.qitech.app/car_rental/rental_agreement/{rental_agreement_id}/messages`

Todas as mensagens são vinculadas a uma análise, utilizando o id enviado no momento do envio da análise.

## Envio de Mensagem

Para que seja realizado o envio de uma mensagem, é necessário realizar a requisição utilizando o método POST no endpoint message, com uma payload que possui os seguintes campos:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| author_document_number | string | CPF formatado de quem está enviando a mensagem |
| author_name | string | Nome de quem está enviando a mensagem |
| message | string | Mensagem sendo enviada |

Exemplo de payload para envio de uma mensagem:

```json
{
  "author_name": "John Sample",
  "author_document_number": "000.000.000-00",
  "message": "Alerta de fraude"
}
```

## Recebimento de Mensagens

Para que as mensagens possam ser exibidas para o atendente, basta realizar a recuperação das mensagens trocadas por meio do endpoint de GET. O endpoint pode receber um query parameter chamado `only_messages_to_show`, que ao receber o valor `true` retorna somente as mensagens que devem ser exibidas na tela do atendente.

Os dados do autor somente são devolvidos quando a mensagem foi produzida por um ser humano.

Retorno no endpoint de recuperação de mensagens:

```json
[
  {
    "author_name": "John Sample",
    "author_document_number": "000.000.000-00",
    "source": "analysis_screen",
    "message": "Análise finalizada",
    "message_date": "2019-11-05T13:34:12-03:00"
  },
  {...}
]
```

---

# Objetos Compartilhados

URL: /documentation/caas/car_rental/objects

Boa parte dos dados são compartilhados entre Reservation e RentalAgreement. Abaixo as definições destes objetos podem ser localizadas de maneira facilitada.

## Objeto *reservation*

```json
{
  "id": "0",
  "channel": "reservation_central",
  "reservation_date": "2020-03-31T08:15:00-03:00",
  "sales_channel" : "PARCERIA TELEFONICA"
}
```

O objeto *reservation* é utilizado no endpoint de *rental_agreement* para representar a reserva que deu origem ao aluguel que será analisado. Este campo é necessário para que um rental_agreement seja vinculado à reserva. Representada da seguinte maneira:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| id | inteiro | Identificador da reserva que deu origem ao aluguel. |
| channel | enumerador | Canal pelo qual foi feito a reserva para este aluguel. |
| reservation_date | DateTime | Data e Hora com fuso-horário do momento em que ocorreu a reserva para este aluguel. |
| sales_channel | string | Canal de vendas pelo qual a reserva foi realizada (ex.: PARCERIA MASTERCARD) |

Existem os seguintes enumeradores para o campo *channel*: `walkin`, `reservation_central`, `app`, `website_mobile`, `website_desktop`, `partnerships` e `third_parties`.

## Objeto *car*

```json
{
  "model_group": "C",
  "upgrade_model_group": "SV",
  "group_description": "Sedan Médio 1.4",
  "rental_daily_price": 48496
}
```

O objeto *car* representa um veículo que está sendo reservado (endpoint de *reservation*) ou retirado (endpoint de *rental_agreement*). Os dados enviados são:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| **model_group** | string | O grupo do veículo, em letras maiúsculas. *(obrigatório)* |
| upgrade_model_group | string | O grupo do veículo do upgrade, em letras maiúsculas. |
| group_description | string | Uma descrição do grupo do veículo |
| rental_daily_price | inteiro | O valor da diária cobrado |

## Objeto *client*

O objeto de *client* representa os dados referentes ao cliente que está fazendo a reserva ou retirada do veículo.

### Objeto *client (v1)*

O exemplo "v1" representa o payload de exemplo **antes da migração da scoragem principal para a reserva**. Tanto para reservas quanto para rental_agreements.

```json
{
  "type": "natural_person",
  "document_number": "123.456.789-00",
  "name": "John Sample",
  "gender": "female",
  "birthdate": "2001-01-15",
  "mother_name": "Mary Sample",
  "email": "john.sample@sample.com.br",
  "allowed_information_on_email": true,
  "face_picture": "c77d1925-0e72-4634-8393-395dbbce498d",
  "additional_pictures": [
    "718b8caa-8ef5-446c-b101-2dbf6c7e401f",
    "9c67f365-1427-4889-b963-d3729d437ff3",
    "8006f82c-3a80-4371-914e-e88c91507711",
    "42c6909e-51aa-4b6d-972f-f4684a047993",
    "b7a88947-96bd-4557-81e9-a69a3c84f428"
  ],
  "total_rents": 6,
  "fidelity_points": 1200,
  "documents": {
    "rg": {
      "document_number": "00000000",
      "issuer": "SSP"
    },
    "cnh": {
      "document_number": "000000000",
      "security_code": "00000",
      "first_issuance": "2015-07-20",
      "expiration_date": "2030-07-26",
      "state": "SP"
    }
  },
  "residential_address": {
    "street": "Av Brigadeiro Faria Lima",
    "number": "2391",
    "neighborhood": "Jardins",
    "city": "SÃO PAULO",
    "uf": "SP",
    "complement": "",
    "postal_code": "00000-000"
  },
  "commercial_address": {
    "street": "Av Brigadeiro Faria Lima",
    "number": "2391",
    "neighborhood": "Jardins",
    "city": "SÃO PAULO",
    "uf": "SP",
    "complement": "",
    "postal_code": "00000-000"
  },
  "phones": [
    {
      "international_dial_code": "55",
      "area_code": "11",
      "number": "00000-0000",
      "type": "mobile"
    },
    {
      "international_dial_code": "55",
      "area_code": "11",
      "number": "00000-0000",
      "type": "residential"
    }
  ]
}
```

| nome | tipo | descrição |
| ---- | :----: | --------- |
| **type** | enum | Enumerador que define tipo do cliente. *(obrigatório)* |
| **document_number** | string | O CPF ou Passaporte do cliente. *(obrigatório)* |
| **name** | string | O nome completo do cliente. *(obrigatório)* |
| **gender** | enum | O gênero do cliente. *(obrigatório)* |
| birthdate | date | Data de nascimento do cliente. |
| mother_name | string | O nome completo da mãe do cliente. |
| **email** | string | O email informado pelo cliente. *(obrigatório)* |
| **allowed_information_on_email** | booleano | Flag que indica se o cliente permitiu o envio de e-mails de marketing no momento do cadastro. *(obrigatório)* |
| face_picture | GUID | GUID da imagem previamente enviada cujo conteúdo é uma foto do rosto do cliente. |
| additional_pictures | List of GUIDs | Lista de GUIDs das imagens adicionais enviadas de rostos e documentos dos clientes. |
| total_rents | integer | Quantidade total de aluguéis do cliente. |
| fidelity_points | integer | Quantidade de pontos de fidelidade do cliente. |
| **documents** | *documents* | Objeto que contém o detalhamento dos documentos do cliente. *(obrigatório)* |
| residential_address | *address* | Endereço residencial do cliente. |
| commercial_address | *address* | Endereço comercial do cliente. |
| **phones** | List of *phone* | Lista com os telefones do cliente. *(obrigatório)* |

Existem os seguintes enumeradores para o campo *type*: `natural_person`, `legal_person`, `replacement`, `fleet`, `uber`, `enterprise` e `agencia`.

Existem os seguintes enumeradores para o campo *gender*: `male`, `female` e `undefined`.

### Objeto *client (v2)*

Esta seção diz respeito às informações necessárias para o fluxo de análise de fraude primariamente na reserva.

O exemplo do objeto de "client (v2)" representa o payload de exemplo **posterior à migração da scoragem principal para a reserva**. Tanto para reservas quanto para rental_agreements.

```json
{
  "type": "natural_person",
  "document_number": "123.456.789-00",
  "name": "John Sample",
  "gender": "female",
  "birthdate": "2001-01-15",
  "mother_name": "Mary Sample",
  "email": "john.sample@sample.com.br",
  "allowed_information_on_email": true,
  "face_picture": "c77d1925-0e72-4634-8393-395dbbce498d",
  "additional_pictures": [
    "718b8caa-8ef5-446c-b101-2dbf6c7e401f",
    "9c67f365-1427-4889-b963-d3729d437ff3",
    "8006f82c-3a80-4371-914e-e88c91507711",
    "42c6909e-51aa-4b6d-972f-f4684a047993",
    "b7a88947-96bd-4557-81e9-a69a3c84f428"
  ],
  "total_rents": 6,
  "fidelity_points": 1200,
  "documents": {
    "rg": {
      "document_number": "00000000",
      "issuer": "SSP"
    },
    "cnh": {
      "document_number": "000000000",
      "security_code": "00000",
      "first_issuance": "2015-07-20",
      "expiration_date": "2030-07-26",
      "state": "SP"
    }
  },
  "residential_address": {
    "street": "Av Brigadeiro Faria Lima",
    "number": "2391",
    "neighborhood": "Jardins",
    "city": "SÃO PAULO",
    "uf": "SP",
    "complement": "",
    "postal_code": "00000-000"
  },
  "commercial_address": {
    "street": "Av Brigadeiro Faria Lima",
    "number": "2391",
    "neighborhood": "Jardins",
    "city": "SÃO PAULO",
    "uf": "SP",
    "complement": "",
    "postal_code": "00000-000"
  },
  "phones": [
    {
      "international_dial_code": "55",
      "area_code": "11",
      "number": "00000-0000",
      "type": "mobile"
    },
    {
      "international_dial_code": "55",
      "area_code": "11",
      "number": "00000-0000",
      "type": "residential"
    }
  ]
}
```

| nome | tipo | descrição |
| ---- | :----: | --------- |
| **type** | enum | Enumerador que define tipo do cliente. - type esperados: "natural_person", "legal_person", "replacement", "fleet", "uber", "agencia", "uber_semanal" *(obrigatório)* |
| **document_number** | string | O CPF ou Passaporte do cliente. *(obrigatório)* |
| name | string | O nome completo do cliente. |
| **gender** | enum | O gênero do cliente. *(obrigatório)* |
| birthdate | date | Data de nascimento do cliente. |
| mother_name | string | O nome completo da mãe do cliente. |
| email | string | O email informado pelo cliente. |
| allowed_information_on_email | booleano | Flag que indica se o cliente permitiu o envio de e-mails de marketing no momento do cadastro. *(obrigatório)* |
| face_picture | GUID | GUID da imagem previamente enviada cujo conteúdo é uma foto do rosto do cliente. |
| additional_pictures | List of GUIDs | Lista de GUIDs das imagens adicionais enviadas de rostos e documentos dos clientes. |
| total_rents | integer | Quantidade total de aluguéis do cliente. |
| fidelity_points | integer | Quantidade de pontos de fidelidade do cliente. |
| **documents** | *documents* | Objeto que contém o detalhamento dos documentos do cliente. *(obrigatório)* |
| residential_address | *address* | Endereço residencial do cliente. |
| commercial_address | *address* | Endereço comercial do cliente. |
| **phones** | List of *phone* | Lista com os telefones do cliente. *(obrigatório)* |

Existem os seguintes enumeradores para o campo *type*: `natural_person`, `legal_person`, `replacement`, `fleet`, `uber`, `enterprise` e `agencia`.

Existem os seguintes enumeradores para o campo *gender*: `male`, `female` e `undefined`.

## Objeto *participant*

O objeto *participant* representa uma pessoa envolvida no aluguel que não é o locatário principal, isto é, um **motorista adicional** ou o **responsável financeiro**. É a definição utilizada tanto na lista `additional_drivers` quanto no campo `financial_manager` de um RentalAgreement.

Sua estrutura é a mesma do objeto *client*, de maneira que a mesma implementação de serialização pode ser reaproveitada.

:::note
Cada participante enviado passa pela mesma análise antifraude aplicada ao locatário principal, porém o resultado destas análises **não altera o fraud_status** do RentalAgreement.
:::

```json
{
  "type": "natural_person",
  "segment": "ota",
  "document_number": "987.654.321-00",
  "name": "Jane Sample",
  "gender": "female",
  "birthdate": "1998-05-22",
  "mother_name": "Mary Sample",
  "email": "jane.sample@sample.com.br",
  "allowed_information_on_email": true,
  "face_picture": "e3b0c442-98fc-1c14-9afb-f4c8996fb924",
  "additional_pictures": [
    "718b8caa-8ef5-446c-b101-2dbf6c7e401f"
  ],
  "total_rents": 2,
  "fidelity_points": 0,
  "documents": {
    "rg": {
      "document_number": "00000000",
      "issuer": "SSP"
    },
    "cnh": {
      "document_number": "000000000",
      "security_code": "00000",
      "first_issuance": "2018-03-10",
      "expiration_date": "2028-03-10",
      "state": "SP"
    }
  },
  "residential_address": {
    "street": "Av Brigadeiro Faria Lima",
    "number": "2391",
    "neighborhood": "Jardins",
    "city": "SÃO PAULO",
    "uf": "SP",
    "complement": "",
    "postal_code": "00000-000",
    "country": "BRA"
  },
  "phones": [
    {
      "international_dial_code": "55",
      "area_code": "11",
      "number": "00000-0000",
      "type": "mobile"
    }
  ]
}
```

| nome | tipo | descrição |
| ---- | :----: | --------- |
| **type** | enum | Enumerador que define o tipo do participante. *(obrigatório)* |
| segment | string | Segmento ao qual o participante pertence. |
| **document_number** | string | O CPF, CNPJ ou Passaporte do participante. *(obrigatório)* |
| **name** | string | O nome completo do participante. *(obrigatório)* |
| **gender** | enum | O gênero do participante. *(obrigatório)* |
| birthdate | date | Data de nascimento do participante. |
| mother_name | string | O nome completo da mãe do participante. |
| **email** | string | O email informado pelo participante. *(obrigatório)* |
| **allowed_information_on_email** | booleano | Flag que indica se o participante permitiu o envio de e-mails de marketing no momento do cadastro. *(obrigatório)* |
| face_picture | GUID | GUID da imagem previamente enviada cujo conteúdo é uma foto do rosto do participante. |
| additional_pictures | List of GUIDs | Lista de GUIDs das imagens adicionais enviadas de rostos e documentos do participante. |
| total_rents | integer | Quantidade total de aluguéis do participante. |
| fidelity_points | integer | Quantidade de pontos de fidelidade do participante. |
| **documents** | *documents* | Objeto que contém o detalhamento dos documentos do participante. *(obrigatório)* |
| residential_address | *address* | Endereço residencial do participante. |
| commercial_address | *address* | Endereço comercial do participante. |
| **phones** | List of *phone* | Lista com os telefones do participante. *(obrigatório)* |

Existem os seguintes enumeradores para o campo *type*: `natural_person`, `legal_person`, `replacement`, `fleet`, `uber`, `enterprise`, `agencia` e `uber_semanal`.

Existem os seguintes enumeradores para o campo *gender*: `male`, `female` e `undefined`.

## Objeto *billing*

```json
{
  "name": "Agência AAA",
  "document_number": "00.000.000/0001-00",
  "voucher_type":"ABCD75",
  "voucher_description": "Pagamento pela Agência"
}
```

O objeto *billing* é utilizado para representar quem é o responsável pelo pagamento do aluguel, e é representado da seguinte maneira:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| name | string | Nome da pessoa ou empresa responsável pelo pagamento do aluguel. |
| document_number | string | CPF, CNPJ ou Passaporte da pessoa ou empresa responsável pelo pagamento do aluguel. |
| voucher_type | string | Código alfanumérico que representa o tipo do voucher utilizado. |
| voucher_description | string | Descrição do tipo de voucher utilizado. |

## Objeto *address*

```json
{
  "street": "Rua do Exemplo",
  "number": "111",
  "neighborhood": "Bairro do Teste",
  "city": "Aparecida de Goiânia",
  "uf": "GO",
  "complement": "",
  "postal_code": "00000-000"
}
```

O objeto *address* é utilizado para representar endereços em toda a API, endereços no território brasileiro são representados da seguinte maneira:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| street | string | Rua do endereço, incluindo o logradouro, evitando, se possível, abreviações. |
| number | string | Número do imóvel, incluindo letras caso possua. |
| neighborhood | string | Bairro, sem abreviações. **e.g.: Santa Felicidade** |
| city | string | Nome completo da cidade, sem abreviações |
| uf | string | A unidade federativa, com duas letras maiúsculas. **e.g.: SP** |
| complement | string | Quaisquer complementos para localizar o imóvel. **e.g.: Apartamento 101, Conjunto 12** |
| postal_code | string | O código postal da localidade, contendo o hífen. |
| country | string | Código ISO 3166-1 alfa-3 do país do endereço. |

No caso dos endereços cujo país não seja Brasil ("BRA"), o postal_code e a unidade federativa poderão ser preenchidos livremente.

## Objeto *documents*

O objeto *documents* é utilizado para representar o detalhamento dos dados dos documentos informados pelo cliente. O objeto é representado da seguinte maneira:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| rg | *rg* | Objeto que descreve as informações do RG do cliente. |
| cnh | *cnh* | Objeto que descreve as informações da CNH do cliente. |
| foreign_document | *foreign_document* | Objeto que descreve as informações do documento estrangeiro do cliente. |

## Objeto *rg*

O objeto *rg* é utilizado para representar o detalhamento dos dados do RG informados pelo cliente. O objeto é representado da seguinte maneira:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| document_number | string | Número do RG do cliente. |
| issuer | string | Órgão emissor e estado de emissão do RG do cliente. |

## Objeto *cnh*

O objeto *cnh* é utilizado para representar o detalhamento dos dados da CNH informados pelo cliente. O objeto é representado da seguinte maneira:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| document_number | string | Número de Registro da CNH do cliente. |
| security_code | string | Código de segurança da CNH do cliente. |
| first_issuance | date | Data da primeira emissão da CNH do cliente |
| expiration_date | string | Data de validade da CNH do cliente |
| state | string | Estado de emissão da CNH do cliente. |

## Objeto *foreign_document*

O objeto *foreign_document* é utilizado para representar o documento estrangeiro informado pelo cliente. O objeto é representado da seguinte maneira:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| document_number | string | Número do documento estrangeiro do cliente. |
| document_type | enum | Tipo do documento estrangeiro. Aceita os valores `passport` e `other`. |
| issuer_country | string | Código ISO 3166-1 alfa-3 do país emissor do documento. |

## Objeto *phone*

```json
{
  "international_dial_code": "1",
  "area_code": "11",
  "number": "99999-9999",
  "type": "mobile"
}
```

Um objeto phone representa um número telefônico, dentro ou fora do Brasil e sua classificação. Para isso, os campos são:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| **international_dial_code** | string | Código de discagem internacional, sem zero ou +, somente números. *(obrigatório)* |
| **area_code** | string | Código de área, sem zero, somente números. *(obrigatório)* |
| **number** | string | Número do telefone, sem o hífen. *(obrigatório)* |
| **type** | enum | Tipo de número: celular, residencial, comercial, etc. *(obrigatório)* |

Existem os seguintes enumeradores para tipo de telefone: `residential`, `commercial`, `mobile`.

## Objeto *coverage*

```json
{
  "description": "S/ PROTEÇÃO AMERICAN PLATINUM",
  "price": 0
}
```

Um objeto coverage está relacionado a uma cobertura contratada pelo locatário.

| nome | tipo | descrição |
| :----: | :----: | --------- |
| **description** | string | Descrição da cobertura contratada. *(obrigatório)* |
| **price** | integer | Preço diário da cobertura. *(obrigatório)* |

---

# Envio de Resultado Quiz

URL: /documentation/caas/car_rental/quiz

Para o envio do resultado Quiz, para que apareça na interface gráfica, o seguinte endpoint deve ser utilizado:

`POST https://api.caas.qitech.app/car_rental/rental_agreement/{rental_agreement_id}/quiz_result`

O resultado do quiz é vinculado a uma análise, utilizando o id enviado no momento do envio da análise.

## Envio do Quiz

Para que seja enviado o resultado do Quiz, é necessário realizar a requisição utilizando o método POST no endpoint quiz_result, com uma payload que possui os seguintes campos:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| score | number | Valor numérico do score do Quiz |
| result_enum | string | Enumerador do resultado do quiz: `low_risk`, `medium_risk`, `high_risk` |
| result_description | string | Descrição do resultado do quiz: "Baixo Risco", "Médio Risco", "Alto Risco" e outros |

Exemplo de payload para envio do resultado do Quiz:

```json
{
  "score": 950,
  "result_enum": "low_risk",
  "result_description": "Baixo Risco"
}
```

---

# RentalAgreement-v1

URL: /documentation/caas/car_rental/rental_agreement

Ao realizar a retirada de um veículo na loja, o locatário dá início ao seu processo de anti-fraude. Os dados enviados deverão ser os dados finais, que não serão alterados. Isto é importante para garantir dois pontos:

- Consistência dos dados na base de dados do Antifraude
- Avaliação realista do risco

O processo de análise consiste em enviar um RentalAgreement no endpoint adequado e esperar a resposta. Existem oito resultados possíveis, devolvido na flag **fraud_status**:

| Resultado | Descrição |
| :---------: | --------- |
| Aprovado Automaticamente | Recomenda-se que este aluguel seja aprovado |
| Negado Automaticamente | Recomenda-se que este aluguel seja reprovado |
| Derivado para análise manual | Nossas regras ou modelos não estão confiantes da decisão e decidiram enviar este aluguel para a análise manual. |
| Aprovado Manualmente | Após análise manual, o analista escolheu aprovar o aluguel |
| Reprovado Manualmente | Após análise manual, o analista escolheu reprovar o aluguel |
| Desafiado Manualmente | Após análise manual, o analista retorna para a loja que a CNH e/ou Selfie estão incorretas e/ou com baixa qualidade |
| Pendente | As consultas estão demorando mais do que o esperado, este aluguel entrou em uma fila de análise automática e será respondido por meio de Webhook |
| Não analisado | A consulta foi enviada com a flag de análise falsa, o que significa que nossos sistemas não deverão retornar parecer |

### Dinâmica dos Status

Ao recuperar um objeto do tipo RentalAgreement os status estão disponíveis. Além dos status, um histórico de modificações também são retornados para que possa ser consultado no futuro. Estas modificações são entituladas events e possuem, além do novo status, as datas de modificação.

### Dinâmica dos Status - **car_status**

O status **car_status** relacionado a um RentalAgreement indica a situação do carro relacionado a este aluguel, isto é, se o carro foi devolvido ou não. Os seguintes enumeradores existem para este status:

- `rented`
- `returned`
- `recovered`
- `written_off`

### Dinâmica dos Status - **fraud_status**

O status **fraud_status** indica o status da decisão do motor de fraude e possui uma máquina de estados bastante simples:

- `created`
- `automatically_approved`
- `automatically_reproved`
- `in_manual_analysis`
- `manually_approved`
- `manually_reproved`
- `manually_challenged`
- `pending`
- `not_analyzed`

Além disso, o upgrade_status também possui os mesmos enumeradores.

### Motoristas adicionais e responsáveis financeiros

Além do locatário principal, enviado em `client`, um RentalAgreement pode carregar outras pessoas envolvidas no aluguel:

- **Motoristas adicionais** (`additional_drivers`): lista de pessoas autorizadas a conduzir o veículo além do locatário principal.
- **Responsável financeiro** (`financial_manager`): pessoa física ou jurídica indicada como responsável pelo pagamento do aluguel. Existe no máximo um responsável financeiro por aluguel.

Ambos os campos utilizam a definição do objeto *participant*, cuja estrutura é idêntica à do objeto *client*.

Cada participante enviado passa pelas **mesmas consultas e análises antifraude** aplicadas ao locatário principal, de maneira que estes dados também alimentam a base de dados do Antifraude. O resultado individual de cada participante é devolvido na resposta da análise, conforme descrito em [Enviar um RentalAgreement](#enviar-um-rentalagreement). No entanto, este resultado **não altera o fraud_status do RentalAgreement**, que continua sendo determinado pela avaliação do locatário principal.

Ambos os campos são opcionais e podem ser omitidos quando não houver participantes além do locatário principal.

## Definição do Objeto

```json
{
  "id": "bca6268e-918a-4658-9161-a10b00a631ab",
  "rental_agreement_code" : "12345678",
  "rental_agreement_date": "2020-03-31T10:30:00-03:00",
  "car_rental_estimated_final_date":  "2020-04-01T10:28:00-03:00",
  "reservation": {
    "id": "0",
    "channel": "reservation_central",
    "reservation_date": "2020-03-31T08:15:00-03:00",
    "sales_channel" : "PARCERIA TELEFONICA"
  },
  "rental_store": "SAOP",
  "rental_store_group": "GSP",
  "rental_store_type": "LOJA DE RUA",
  "devolution_store": "SAOP",
  "risky_antecedence": true,
  "car": {
    "model_group": "AM",
    "upgrade_model_group": "SV",
    "rental_daily_price" : 48496,
    "risky_model_group": true,
    "risky_upgrade_model_group": true
  },
  "client": {
    "type": "natural_person",
    "segment": "ota",
    "document_number": "123.456.789-00",
    "name": "John Sample",
    "gender": "female",
    "birthdate": "2001-01-15",
    "mother_name": "Mary Sample",
    "email": "john.sample@sample.com.br",
    "allowed_information_on_email": true,
    "face_picture": "c77d1925-0e72-4634-8393-395dbbce498d",
    "additional_pictures": [
      "718b8caa-8ef5-446c-b101-2dbf6c7e401f",
      "9c67f365-1427-4889-b963-d3729d437ff3",
      "8006f82c-3a80-4371-914e-e88c91507711",
      "42c6909e-51aa-4b6d-972f-f4684a047993",
      "b7a88947-96bd-4557-81e9-a69a3c84f428"
    ],
    "total_rents": 6,
    "fidelity_points": 1200,
    "documents": {
      "rg": {
        "document_number": "00000000",
        "issuer": "SSP"
      },
      "cnh": {
        "document_number": "000000000",
        "security_code": "00000",
        "first_issuance": "2015-07-20",
        "expiration_date": "2030-07-26",
        "state": "SP"
      }
    },
    "residential_address": {
      "street": "Av Brigadeiro Faria Lima",
      "number": "2391",
      "neighborhood": "Jardins",
      "city": "SÃO PAULO",
      "uf": "SP",
      "complement": "",
      "postal_code": "00000-000"
    },
    "commercial_address": {
      "street": "Av Brigadeiro Faria Lima",
      "number": "2391",
      "neighborhood": "Jardins",
      "city": "SÃO PAULO",
      "uf": "SP",
      "complement": "",
      "postal_code": "00000-000"
    },
    "phones": [
      {
        "international_dial_code": "55",
        "area_code": "11",
        "number": "00000-0000",
        "type": "mobile"
      },
      {
        "international_dial_code": "55",
        "area_code": "11",
        "number": "00000-0000",
        "type": "residential"
      }
    ]
  },
  "additional_drivers": [
    {
      "type": "natural_person",
      "document_number": "987.654.321-00",
      "name": "Jane Sample",
      "gender": "female",
      "email": "jane.sample@sample.com.br",
      "allowed_information_on_email": true,
      "face_picture": "e3b0c442-98fc-1c14-9afb-f4c8996fb924",
      "documents": {
        "cnh": {
          "document_number": "000000000",
          "security_code": "00000",
          "first_issuance": "2018-03-10",
          "expiration_date": "2028-03-10",
          "state": "SP"
        }
      },
      "phones": [
        {
          "international_dial_code": "55",
          "area_code": "11",
          "number": "00000-0000",
          "type": "mobile"
        }
      ]
    }
  ],
  "financial_manager": {
    "type": "legal_person",
    "document_number": "00.000.000/0001-00",
    "name": "Empresa Sample LTDA",
    "gender": "undefined",
    "email": "financeiro@sample.com.br",
    "allowed_information_on_email": false,
    "documents": {},
    "phones": [
      {
        "international_dial_code": "55",
        "area_code": "11",
        "number": "00000-0000",
        "type": "commercial"
      }
    ]
  },
  "coverages": [
    {
      "description": "S/ PROTEÇÃO AMERICAN PLATINUM",
      "price": 0
    },
    {
      "description": "PROTEÇÃO OCUPANTES E TERCEIROS",
      "price": 1668
    }
  ],
  "billing": {
    "name": "Agência AAA",
    "document_number": "00.000.000/0001-00",
    "voucher_type": "ABCD75",
    "voucher_description": "Pagamento pela agência"
  },
  "fare_name": "Mensal",
  "rental_price": 43300,
  "extra_hours": 0,
  "extra_hours_price": 0,
  "discount": 0,
  "prepayment_discount": 100,
  "extra_kms": 0,
  "extra_kms_price": 0,
  "third_party_coverage_price": 1490,
  "coverage_price": 0,
  "additional_driver_price": 1000,
  "driver_service_price": 1000,
  "additional_expenses": 1000,
  "devolution_fee": 0,
  "administration_fee": 5374,
  "discount_partial_coverage": 50,
  "free_day_discount": 20000,
  "final_price": 50165,
  "pre_authorization_amount": 0,
  "coverage_deductible_amount": 0,
  "upgrade_reason": "granted"
}
```

Todas as trocas de informação de um RentalAgreement utilizam a seguinte definição para este objeto. Em alguns casos, para facilitar a implementação e diminuir o fluxo de dados entre as partes, algumas informações poderão ser omitidas.

| nome | tipo | descrição |
| :----: | :----: | --------- |
| **id** | string | Identificador da requisição de análise no sistema do cliente. **É essencial que este número seja único para cada aluguel.** *(obrigatório)* |
| **rental_agreement_code** | string | Identificador do RentalAgreement no sistema do cliente. *(obrigatório)* |
| **rental_agreement_date** | DateTime | Data e Hora com fuso-horário da retirada do veículo do aluguel que está ocorrendo. *(obrigatório)* |
| **car_rental_estimated_final_date** | DateTime | Data e Hora com fuso-horário de quando o carro deve ser resolvido. *(obrigatório)* |
| **reservation** | *reservation* | Objeto que carrega as propriedades da reserva que deu origem a esse aluguel. *(obrigatório)* |
| **rental_store** | *store* | Loja onde o carro está sendo retirado. *(obrigatório)* |
| rental_store_group | *store* | Filial da loja onde o carro está sendo retirado |
| rental_store_type | *store* | Tipo da loja onde o carro será retirado |
| **devolution_store** | *store* | Loja onde o carro será devolvido, pode ou não ser a mesma loja de retirada. *(obrigatório)* |
| **car** | *car* | Carro que está sendo retirado - é importante que este valor seja, de fato, o carro sendo retirado. *(obrigatório)* |
| **client** | *client* | Objeto que carrega as informações do cliente que está retirando o veículo. *(obrigatório)* |
| additional_drivers | List of *participant* | Lista com os motoristas adicionais autorizados a conduzir o veículo neste aluguel. |
| financial_manager | *participant* | Pessoa física ou jurídica indicada como responsável financeiro deste aluguel. |
| **coverages** | List of *coverage* | Lista de objetos coverage que descrevem as coberturas de seguro contratadas pelo cliente. *(obrigatório)* |
| **billing** | *billing* | Objeto que descreve os detalhes da pessoa ou empresa responsável pelo pagamento do aluguel. *(obrigatório)* |
| **rental_price** | integer | Preço do aluguel, em centavos. *(obrigatório)* |
| **extra_hours** | integer | Quantidade de horas extras contratadas. *(obrigatório)* |
| **extra_hours_price** | integer | Preço das horas extras contratadas, em centavos. *(obrigatório)* |
| **discount** | inteiro | Desconto concedido por quaisquer motivos, em centavos. *(obrigatório)* |
| **prepayment_discount** | inteiro | Desconto por pagamento antecipado. |
| **extra_kms** | integer | Quantidade de kilômetros extras contratados. *(obrigatório)* |
| **extra_kms_price** | integer | Preço de kilômetros extras contratados, em centavos. *(obrigatório)* |
| **third_party_coverage_price** | integer | Preço do seguro de terceiros, em centavos. *(obrigatório)* |
| **coverage_price** | integer | Preço do seguro contratado, em centavos. *(obrigatório)* |
| additional_driver_price | integer | Preço total do(s) motoristas adicionais contratados, em centavos. |
| driver_service_price | integer | Preço total do serviço de motorista contratado, em centavos. |
| additional_expenses | integer | Despesas adicionais, em centavos |
| **devolution_fee** | integer | Preço da taxa de devolução, em centavos. *(obrigatório)* |
| **administration_fee** | integer | Preço da taxa de administração, em centavos. *(obrigatório)* |
| **discount_partial_coverage** | integer | Desconto de proteção parcial, em centavos. |
| **free_day_discount** | integer | Desconto de Free Day, em centavos. |
| **final_price** | integer | Preço final do aluguel, em centavos. *(obrigatório)* |
| pre_authorization_amount | integer | Valor da pré-autorização, em centavos. |
| **coverage_deductible_amount** | integer | Valor dedutível da cobertura, em centavos. *(obrigatório)* |
| upgrade_reason | enum | Tipo de upgrade (Concedido ou Comprado) - Aceita os valores `granted` e `bought` respectivamente |

## Enviar um RentalAgreement

Exemplo de Request:

```json
{
  "id": "bca6268e-918a-4658-9161-a10b00a631ab",
  ...
}
```

Exemplo de Retorno:

```json
{
  "id": "bca6268e-918a-4658-9161-a10b00a631ab",
  "fraud_status": "automatically_approved",
  "financial_manager": {
    "fraud_status": "automatically_approved"
  },
  "additional_drivers": [
    {
      "id": "1111111",
      "fraud_status": "automatically_approved"
    }
  ],
  "pre_authorization_amount": 100000,
  "block_document_number": true,
  "upgrade_status": "automatically_approved",
  "highest_allowed_car_group": "SV",
  "score": 870
}
```

Caso o aluguel tenha sido enviado com motoristas adicionais e/ou responsável financeiro, o resultado individual da análise de cada um deles também é retornado:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| financial_manager.fraud_status | enum | Resultado da análise antifraude do responsável financeiro. Utiliza os mesmos enumeradores do **fraud_status** do RentalAgreement. |
| additional_drivers[].id | string | Identificador do motorista adicional analisado. |
| additional_drivers[].fraud_status | enum | Resultado da análise antifraude daquele motorista adicional. Utiliza os mesmos enumeradores do **fraud_status** do RentalAgreement. |

:::note
Estes status são informativos e independentes: um motorista adicional ou responsável financeiro reprovado **não altera** o **fraud_status** do RentalAgreement. Cabe à locadora decidir o que fazer com o participante reprovado, como recusar a inclusão daquele motorista no aluguel.
:::

Para realizar a avaliação de um aluguel, basta enviar um objeto do tipo RentalAgreement ao seguinte endpoint com a flag setada adequadamente:

`POST https://api.caas.qitech.app/car_rental/rental_agreement?analyze=true`

Além do status do retorno, também é retornado, caso haja, o valor da pré autorização desejada. Caso nenhuma majoração de pré autorização seja identificada, o valor retornado é nulo e não deve ser utilizado.

O grupo máximo que pode ser fornecido naquele RA é disponibilizado na variável `highest_allowed_car_group`. Este valor é configurado na regra de avaliação do RA.

O parâmetro *analyze* existe para evitar que transações que não precisam ser analisadas passem pelos motores de fraude, sujando a base de dados. O valor padrão deste parâmetro é **true**, de maneira que somente alugueis que forem explícitamente retirados da análise não serão analisados.

## Atualizar o status de um RentalAgreement

Corpo da requisição - Na efetivação de um aluguel de um carro:

```json
{
  "car_status": "rented",
  "event_date": "2019-11-05T13:34:12-03:00"
}
```

Corpo da requisição - Na devolução sem incidentes de um carro:

```json
{
  "car_status": "returned",
  "event_date": "2019-11-05T13:34:12-03:00"
}
```

Corpo da requisição - Na devolução mediante recuperação por roubo:

```json
{
  "car_status": "recovered",
  "incident": "theft",
  "event_date": "2019-11-05T13:34:12-03:00"
}
```

Corpo da requisição - Write-off com fraude confirmada:

```json
{
  "car_status": "written_off",
  "incident": "misappropriation",
  "event_date": "2019-11-05T13:34:12-03:00"
}
```

Para garantir a retroalimentação das regras e do modelo de inteligência artificial implementado, é necessário informar ao sistema quando os carros são alugados, devolvidos, ou quando são jogados a perda por fraude. Para isso, requisições com o método PUT devem ser utilizadas, passando-se como referência o id enviado na criação do *rental_agreement*, autenticadas normalmente:

`PUT https://api.caas.qitech.app/car_rental/rental_agreement/{rental_agreement_id}`

Caso o novo status seja *written_off*, os seguintes valores podem ser utilizados no campo **incident**, enviado no body da requisição, que indica o tipo de incidente do aluguel:

| Enumerador | Descrição |
| --------- | ----------- |
| theft | RAs que sofreram um roubo |
| misappropriation | RAs que foram classificados como apropriação indébita |

## Atualizar o veículo de um RentalAgreement

Corpo da requisição - Atualização de um veículo no aluguel:

```json
{
  "car_plate": "ABC1B34",
  "car_model": "Chevrolet Onix",
  "model_group": "B",
  "event_date": "2020-10-15T13:34:12-03:00"
}
```

Para garantir a consistência entre as ocorrências de fraude e os aluguéis e garantir o retreinamento do modelo de score, é necessário informar ao sistema os dados de cada carro quando ele é atrelado ao aluguel. Para isso, requisições com o método POST devem ser utilizadas, passando-se como referência o id enviado na criação do *rental_agreement*, autenticadas normalmente:

`POST https://api.caas.qitech.app/car_rental/rental_agreement/{rental_agreement_id}/car`

No body da requisição devem ser enviados os dados do veículo que está sendo atrelado àquele aluguel:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| car_plate | string | Placa do veículo. |
| car_model | string | Modelo do veículo, incluindo sua marca e modelo (ex.: Jeep Renegade). |
| model_group | string | O grupo do veículo, em letras maiúsculas. |
| event_date | DateTime | Data e Hora com fuso-horário do momento em que ocorreu a associação do carro ao aluguel. |

## Recuperar um RentalAgreement

A fim de recuperar um RentalAgreement específico, basta realizar uma requisição GET. O resultado retornado é o json mais atualizado do RentalAgreement em questão. Caso este identificador não esteja relacionado a nenhum objeto, o HTTP Status 404 é retornado.

`GET https://api.caas.qitech.app/car_rental/rental_agreements/{rental_agreement_id}`

```shell
curl "https://api.caas.qitech.app/car_rental/rental_agreements/{rental_agreement_id}"
  -H "Authorization: TESTETESTETESTE"
```

## Buscar RentalAgreements

Retorno - uma lista de objetos RentalAgreement:

```json
[
  {
    "id": "bca6268e-918a-4658-9161-a10b00a631ab",
    ...
  },
  {
    "id": "13a91409-9793-49b6-8583-9ba575075831",
    ...
  }
]
```

Caso seja necessário buscar um RentalAgreement, um GET com parâmetros de query poderá ser utilizado. O resultado retornado é um JSON que representa uma lista de RentalAgreements. Caso nenhum objeto seja encontrado com os parâmetros enviados, o HTTP Status 200 é retornado com uma lista vazia no corpo da resposta.

`GET https://api.caas.qitech.app/car_rental/rental_agreements?initial_date=2019-10-01&final_date=2019-10-05&page_number=2&page_rows=20`

Os seguintes parâmetros podem ser utilizados para buscar objetos de RentalAgreement:

| Parâmetro | Padrão | Descrição |
| --------- | ----------- | -------------- |
| initial_date | null | Primeira data que deve ser retornada a partir do campo rental_agreement_date |
| final_date | null | Última data que deve ser retornada a partir do campo rental_agreement_date |
| store_code | null | Código da loja de onde os resultados devem ser retornados |
| page_number | 1 | Número da página de resultados desejada |
| page_rows | 50 | Número de objetos máximo a ser retornados em uma consulta |

---

# RentalAgreement-v2

URL: /documentation/caas/car_rental/rental_agreement_v2

Esta seção diz respeito ao fluxo de análise de fraude com a scoragem principal ocorrendo na reserva.

Ao realizar a retirada de um veículo na loja, o locatário dá início ao seu processo de anti-fraude. Os dados enviados deverão ser os dados finais, que não serão alterados. Isto é importante para garantir dois pontos:

- Consistência dos dados na base de dados do Antifraude
- Avaliação realista do risco

O processo de análise consiste em enviar um RentalAgreement no endpoint adequado e esperar a resposta. Existem oito resultados possíveis, devolvido na flag **fraud_status**:

| Resultado | Descrição |
| :---------: | --------- |
| Aprovado Automaticamente | Recomenda-se que este aluguel seja aprovado |
| Negado Automaticamente | Recomenda-se que este aluguel seja reprovado |
| Derivado para análise manual | Nossas regras ou modelos não estão confiantes da decisão e decidiram enviar este aluguel para a análise manual. |
| Aprovado Manualmente | Após análise manual, o analista escolheu aprovar o aluguel |
| Reprovado Manualmente | Após análise manual, o analista escolheu reprovar o aluguel |
| Desafiado Manualmente | Após análise manual, o analista retorna para a loja que a CNH e/ou Selfie estão incorretas e/ou com baixa qualidade |
| Pendente | As consultas estão demorando mais do que o esperado, este aluguel entrou em uma fila de análise automática e será respondido por meio de Webhook |
| Não analisado | A consulta foi enviada com a flag de análise falsa, o que significa que nossos sistemas não deverão retornar parecer |

### Dinâmica dos Status

Ao recuperar um objeto do tipo RentalAgreement os status estão disponíveis. Além dos status, um histórico de modificações também são retornados para que possa ser consultado no futuro. Estas modificações são entituladas events e possuem, além do novo status, as datas de modificação.

### Dinâmica dos Status - **car_status**

O status **car_status** relacionado a um RentalAgreement indica a situação do carro relacionado a este aluguel, isto é, se o carro foi devolvido ou não. Os seguintes enumeradores existem para este status:

- `rented`
- `returned`
- `recovered`
- `written_off`

### Dinâmica dos Status - **fraud_status**

O status **fraud_status** indica o status da decisão do motor de fraude e possui uma máquina de estados bastante simples:

- `created`
- `automatically_approved`
- `automatically_reproved`
- `in_manual_analysis`
- `manually_approved`
- `manually_reproved`
- `manually_challenged`
- `pending`
- `not_analyzed`

Além disso, o upgrade_status também possui os mesmos enumeradores.

## Definição do Objeto

```json
{
  "id": "bca6268e-918a-4658-9161-a10b00a631ab",
  "rental_agreement_code" : "12345678",
  "rental_agreement_date": "2020-03-31T10:30:00-03:00",
  "car_rental_estimated_final_date":  "2020-04-01T10:28:00-03:00",
  "reservation": {
    "id": "0",
    "channel": "reservation_central",
    "reservation_date": "2020-03-31T08:15:00-03:00",
    "sales_channel" : "PARCERIA TELEFONICA"
  },
  "rental_store": "SAOP",
  "rental_store_group": "GSP",
  "rental_store_type": "LOJA DE RUA",
  "devolution_store": "SAOP",
  "risky_antecedence": true,
  "car": {
    "model_group": "AM",
    "upgrade_model_group": "SV",
    "rental_daily_price" : 48496,
    "risky_model_group": true,
    "risky_upgrade_model_group": true
  },
  "client": {
    "type": "natural_person",
    "segment": "ota",
    "document_number": "123.456.789-00",
    "name": "John Sample",
    "gender": "female",
    "birthdate": "2001-01-15",
    "mother_name": "Mary Sample",
    "email": "john.sample@sample.com.br",
    "allowed_information_on_email": true,
    "face_picture": "c77d1925-0e72-4634-8393-395dbbce498d",
    "additional_pictures": [
      "718b8caa-8ef5-446c-b101-2dbf6c7e401f",
      "9c67f365-1427-4889-b963-d3729d437ff3",
      "8006f82c-3a80-4371-914e-e88c91507711",
      "42c6909e-51aa-4b6d-972f-f4684a047993",
      "b7a88947-96bd-4557-81e9-a69a3c84f428"
    ],
    "total_rents": 6,
    "fidelity_points": 1200,
    "documents": {
      "rg": {
        "document_number": "00000000",
        "issuer": "SSP"
      },
      "cnh": {
        "document_number": "000000000",
        "security_code": "00000",
        "first_issuance": "2015-07-20",
        "expiration_date": "2030-07-26",
        "state": "SP"
      }
    },
    "residential_address": {
      "street": "Av Brigadeiro Faria Lima",
      "number": "2391",
      "neighborhood": "Jardins",
      "city": "SÃO PAULO",
      "uf": "SP",
      "complement": "",
      "postal_code": "00000-000"
    },
    "commercial_address": {
      "street": "Av Brigadeiro Faria Lima",
      "number": "2391",
      "neighborhood": "Jardins",
      "city": "SÃO PAULO",
      "uf": "SP",
      "complement": "",
      "postal_code": "00000-000"
    },
    "phones": [
      {
        "international_dial_code": "55",
        "area_code": "11",
        "number": "00000-0000",
        "type": "mobile"
      },
      {
        "international_dial_code": "55",
        "area_code": "11",
        "number": "00000-0000",
        "type": "residential"
      }
    ]
  },
  "coverages": [
    {
      "description": "S/ PROTEÇÃO AMERICAN PLATINUM",
      "price": 0
    },
    {
      "description": "PROTEÇÃO OCUPANTES E TERCEIROS",
      "price": 1668
    }
  ],
  "billing": {
    "name": "Agência AAA",
    "document_number": "00.000.000/0001-00",
    "voucher_type": "ABCD75",
    "voucher_description": "Pagamento pela agência"
  },
  "fare_name": "Mensal",
  "rental_price": 43300,
  "extra_hours": 0,
  "extra_hours_price": 0,
  "discount": 0,
  "prepayment_discount": 100,
  "extra_kms": 0,
  "extra_kms_price": 0,
  "third_party_coverage_price": 1490,
  "coverage_price": 0,
  "additional_driver_price": 1000,
  "driver_service_price": 1000,
  "additional_expenses": 1000,
  "devolution_fee": 0,
  "administration_fee": 5374,
  "discount_partial_coverage": 50,
  "free_day_discount": 20000,
  "final_price": 50165,
  "pre_authorization_amount": 0,
  "coverage_deductible_amount": 0,
  "upgrade_reason": "granted"
}
```

Todas as trocas de informação de um RentalAgreement utilizam a seguinte definição para este objeto. Em alguns casos, para facilitar a implementação e diminuir o fluxo de dados entre as partes, algumas informações poderão ser omitidas.

| nome | tipo | descrição |
| :----: | :----: | --------- |
| **id** | string | Identificador da requisição de análise no sistema do cliente. **É essencial que este número seja único para cada aluguel.** *(obrigatório)* |
| **rental_agreement_code** | string | Identificador do RentalAgreement no sistema do cliente. *(obrigatório)* |
| **rental_agreement_date** | DateTime | Data e Hora com fuso-horário da retirada do veículo do aluguel que está ocorrendo. *(obrigatório)* |
| **car_rental_estimated_final_date** | DateTime | Data e Hora com fuso-horário de quando o carro deve ser resolvido. *(obrigatório)* |
| **reservation** | *reservation* | Objeto que carrega as propriedades da reserva que deu origem a esse aluguel. *(obrigatório)* |
| **rental_store** | *store* | Loja onde o carro está sendo retirado. *(obrigatório)* |
| rental_store_group | *store* | Filial da loja onde o carro está sendo retirado |
| rental_store_type | *store* | Tipo da loja onde o carro será retirado |
| **devolution_store** | *store* | Loja onde o carro será devolvido, pode ou não ser a mesma loja de retirada. *(obrigatório)* |
| **car** | *car* | Carro que está sendo retirado - é importante que este valor seja, de fato, o carro sendo retirado. *(obrigatório)* |
| **client** | *client* | Objeto que carrega as informações do cliente que está retirando o veículo. *(obrigatório)* |
| **coverages** | List of *coverage* | Lista de objetos coverage que descrevem as coberturas de seguro contratadas pelo cliente. *(obrigatório)* |
| **billing** | *billing* | Objeto que descreve os detalhes da pessoa ou empresa responsável pelo pagamento do aluguel. *(obrigatório)* |
| **rental_price** | integer | Preço do aluguel, em centavos. *(obrigatório)* |
| **extra_hours** | integer | Quantidade de horas extras contratadas. *(obrigatório)* |
| **extra_hours_price** | integer | Preço das horas extras contratadas, em centavos. *(obrigatório)* |
| **discount** | inteiro | Desconto concedido por quaisquer motivos, em centavos. *(obrigatório)* |
| **prepayment_discount** | inteiro | Desconto por pagamento antecipado. |
| **extra_kms** | integer | Quantidade de kilômetros extras contratados. *(obrigatório)* |
| **extra_kms_price** | integer | Preço de kilômetros extras contratados, em centavos. *(obrigatório)* |
| **third_party_coverage_price** | integer | Preço do seguro de terceiros, em centavos. *(obrigatório)* |
| **coverage_price** | integer | Preço do seguro contratado, em centavos. *(obrigatório)* |
| additional_driver_price | integer | Preço total do(s) motoristas adicionais contratados, em centavos. |
| driver_service_price | integer | Preço total do serviço de motorista contratado, em centavos. |
| additional_expenses | integer | Despesas adicionais, em centavos |
| **devolution_fee** | integer | Preço da taxa de devolução, em centavos. *(obrigatório)* |
| **administration_fee** | integer | Preço da taxa de administração, em centavos. *(obrigatório)* |
| **discount_partial_coverage** | integer | Desconto de proteção parcial, em centavos. |
| **free_day_discount** | integer | Desconto de Free Day, em centavos. |
| **final_price** | integer | Preço final do aluguel, em centavos. *(obrigatório)* |
| pre_authorization_amount | integer | Valor da pré-autorização, em centavos. |
| **coverage_deductible_amount** | integer | Valor dedutível da cobertura, em centavos. *(obrigatório)* |
| upgrade_reason | enum | Tipo de upgrade (Concedido ou Comprado) - Aceita os valores `granted` e `bought` respectivamente |

## Enviar um RentalAgreement

Exemplo de Request:

```json
{
  "id": "bca6268e-918a-4658-9161-a10b00a631ab",
  ...
}
```

Exemplo de Retorno:

```json
{
  "id": "bca6268e-918a-4658-9161-a10b00a631ab",
  "fraud_status": "automatically_approved",
  "pre_authorization_amount": 100000,
  "block_document_number": true,
  "upgrade_status": "automatically_approved",
  "highest_allowed_car_group": "SV",
  "score": 870
}
```

Para realizar a avaliação de um aluguel, basta enviar um objeto do tipo RentalAgreement ao seguinte endpoint com a flag setada adequadamente:

`POST https://api.caas.qitech.app/car_rental/rental_agreement?analyze=true`

Além do status do retorno, também é retornado, caso haja, o valor da pré autorização desejada. Caso nenhuma majoração de pré autorização seja identificada, o valor retornado é nulo e não deve ser utilizado.

O grupo máximo que pode ser fornecido naquele RA é disponibilizado na variável `highest_allowed_car_group`. Este valor é configurado na regra de avaliação do RA.

O parâmetro *analyze* existe para evitar que transações que não precisam ser analisadas passem pelos motores de fraude, sujando a base de dados. O valor padrão deste parâmetro é **true**, de maneira que somente alugueis que forem explícitamente retirados da análise não serão analisados.

## Atualizar o status de um RentalAgreement

Corpo da requisição - Na efetivação de um aluguel de um carro:

```json
{
  "car_status": "rented",
  "event_date": "2019-11-05T13:34:12-03:00"
}
```

Corpo da requisição - Na devolução sem incidentes de um carro:

```json
{
  "car_status": "returned",
  "event_date": "2019-11-05T13:34:12-03:00"
}
```

Corpo da requisição - Na devolução mediante recuperação por roubo:

```json
{
  "car_status": "recovered",
  "incident": "theft",
  "event_date": "2019-11-05T13:34:12-03:00"
}
```

Corpo da requisição - Write-off com fraude confirmada:

```json
{
  "car_status": "written_off",
  "incident": "misappropriation",
  "event_date": "2019-11-05T13:34:12-03:00"
}
```

Para garantir a retroalimentação das regras e do modelo de inteligência artificial implementado, é necessário informar ao sistema quando os carros são alugados, devolvidos, ou quando são jogados a perda por fraude. Para isso, requisições com o método PUT devem ser utilizadas, passando-se como referência o id enviado na criação do *rental_agreement*, autenticadas normalmente:

`PUT https://api.caas.qitech.app/car_rental/rental_agreement/{rental_agreement_id}`

Caso o novo status seja *written_off*, os seguintes valores podem ser utilizados no campo **incident**, enviado no body da requisição, que indica o tipo de incidente do aluguel:

| Enumerador | Descrição |
| --------- | ----------- |
| theft | RAs que sofreram um roubo |
| misappropriation | RAs que foram classificados como apropriação indébita |

## Atualizar o veículo de um RentalAgreement

Corpo da requisição - Atualização de um veículo no aluguel:

```json
{
  "car_plate": "ABC1B34",
  "car_model": "Chevrolet Onix",
  "model_group": "B",
  "event_date": "2020-10-15T13:34:12-03:00"
}
```

Para garantir a consistência entre as ocorrências de fraude e os aluguéis e garantir o retreinamento do modelo de score, é necessário informar ao sistema os dados de cada carro quando ele é atrelado ao aluguel. Para isso, requisições com o método POST devem ser utilizadas, passando-se como referência o id enviado na criação do *rental_agreement*, autenticadas normalmente:

`POST https://api.caas.qitech.app/car_rental/rental_agreement/{rental_agreement_id}/car`

No body da requisição devem ser enviados os dados do veículo que está sendo atrelado àquele aluguel:

| nome | tipo | descrição |
| ---- | :----: | --------- |
| car_plate | string | Placa do veículo. |
| car_model | string | Modelo do veículo, incluindo sua marca e modelo (ex.: Jeep Renegade). |
| model_group | string | O grupo do veículo, em letras maiúsculas. |
| event_date | DateTime | Data e Hora com fuso-horário do momento em que ocorreu a associação do carro ao aluguel. |

## Recuperar um RentalAgreement

A fim de recuperar um RentalAgreement específico, basta realizar uma requisição GET. O resultado retornado é o json mais atualizado do RentalAgreement em questão. Caso este identificador não esteja relacionado a nenhum objeto, o HTTP Status 404 é retornado.

`GET https://api.caas.qitech.app/car_rental/rental_agreements/{rental_agreement_id}`

```shell
curl "https://api.caas.qitech.app/car_rental/rental_agreements/{rental_agreement_id}"
  -H "Authorization: TESTETESTETESTE"
```

## Buscar RentalAgreements

Retorno - uma lista de objetos RentalAgreement:

```json
[
  {
    "id": "bca6268e-918a-4658-9161-a10b00a631ab",
    ...
  },
  {
    "id": "13a91409-9793-49b6-8583-9ba575075831",
    ...
  }
]
```

Caso seja necessário buscar um RentalAgreement, um GET com parâmetros de query poderá ser utilizado. O resultado retornado é um JSON que representa uma lista de RentalAgreements. Caso nenhum objeto seja encontrado com os parâmetros enviados, o HTTP Status 200 é retornado com uma lista vazia no corpo da resposta.

`GET https://api.caas.qitech.app/car_rental/rental_agreements?initial_date=2019-10-01&final_date=2019-10-05&page_number=2&page_rows=20`

Os seguintes parâmetros podem ser utilizados para buscar objetos de RentalAgreement:

| Parâmetro | Padrão | Descrição |
| --------- | ----------- | -------------- |
| initial_date | null | Primeira data que deve ser retornada a partir do campo rental_agreement_date |
| final_date | null | Última data que deve ser retornada a partir do campo rental_agreement_date |
| store_code | null | Código da loja de onde os resultados devem ser retornados |
| page_number | 1 | Número da página de resultados desejada |
| page_rows | 50 | Número de objetos máximo a ser retornados em uma consulta |

---

# Reservation-v1

URL: /documentation/caas/car_rental/reservation

Ao realizar a reserva de um veículo, o locatário dá início ao seu processo de anti-fraude. Os dados enviados deverão ser os dados finais da reserva, que não serão alterados. Isto é importante para garantir dois pontos:

- Consistência dos dados na base de dados do Antifraude
- Avaliação realista do risco

O processo de análise consiste em enviar uma Reservation no endpoint adequado e esperar a resposta. Existem oito resultados possíveis, devolvido na flag **fraud_status**:

| Resultado | Descrição |
| :---------: | --------- |
| Aprovado Automaticamente | Recomenda-se que este aluguel seja aprovado |
| Negado Automaticamente | Recomenda-se que este aluguel seja reprovado |
| Derivado para análise manual | Nossas regras ou modelos não estão confiantes da decisão e decidiram enviar este aluguel para a análise manual. |
| Aprovado Manualmente | Após análise manual, o analista escolheu aprovar o aluguel |
| Reprovado Manualmente | Após análise manual, o analista escolheu reprovar o aluguel |
| Desafiado Manualmente | Após análise manual, o analista retorna para a loja que a CNH e/ou Selfie estão incorretas e/ou com baixa qualidade |
| Pendente | As consultas estão demorando mais do que o esperado, este aluguel entrou em uma fila de análise automática e será respondido por meio de Webhook |
| Não analisado | A consulta foi enviada com a flag de análise falsa, o que significa que nossos sistemas não deverão retornar parecer |

### Dinâmica dos Status

Ao recuperar um objeto do tipo Reservation os status estão disponíveis. Além dos status, um histórico de modificações também são retornados para que possa ser consultado no futuro. Estas modificações são entituladas events e possuem, além do novo status, as datas de modificação.

### Dinâmica dos Status - **fraud_status**

O status **fraud_status** indica o status da decisão do motor de fraude e possui uma máquina de estados bastante simples:

- `created`
- `automatically_approved`
- `automatically_reproved`
- `in_manual_analysis`
- `manually_approved`
- `manually_reproved`
- `pending`
- `not_analyzed`

## Definição do Objeto

```json
{
  "id": "bca6268e-918a-4658-9161-a10b00a631ab",
  "reservation_code": "211034324",
  "reservation_date": "2020-03-31T08:15:00-03:00",
  "rental_agreement_date": "2020-03-31T10:30:00-03:00",
  "car_rental_estimated_final_date":  "2020-04-01T10:28:00-03:00",
  "channel": "reservation_central",
  "sales_channel" : "PARCERIA TELEFONICA",
  "rental_store": "SAOP",
  "rental_store_group": "GSP",
  "rental_store_type": "LOJA DE RUA",
  "devolution_store": "SAOP",
  "car": {
    "model_group": "SV",
    "rental_daily_price" : 48496
  },
  "client": {
    "type": "natural_person",
    "segment": "ota",
    "document_number": "123.456.789-00",
    "name": "John Sample",
    "gender": "female",
    "birthdate": "2001-01-15",
    "mother_name": "Mary Sample",
    "email": "john.sample@sample.com.br",
    "allowed_information_on_email": true,
    "face_picture": "c77d1925-0e72-4634-8393-395dbbce498d",
    "additional_pictures": [
      "718b8caa-8ef5-446c-b101-2dbf6c7e401f",
      "9c67f365-1427-4889-b963-d3729d437ff3",
      "8006f82c-3a80-4371-914e-e88c91507711",
      "42c6909e-51aa-4b6d-972f-f4684a047993",
      "b7a88947-96bd-4557-81e9-a69a3c84f428"
    ],
    "documents": {
      "rg": {
        "document_number": "00000000",
        "issuer": "SSP"
      },
      "cnh": {
        "document_number": "000000000",
        "security_code": "00000",
        "first_issuance": "2015-07-20",
        "expiration_date": "2030-07-26",
        "state": "SP"
      }
    },
    "residential_address": {
      "street": "Av Brigadeiro Faria Lima",
      "number": "2391",
      "neighborhood": "Jardins",
      "city": "SÃO PAULO",
      "uf": "SP",
      "complement": "",
      "postal_code": "00000-000"
    },
    "commercial_address": {
      "street": "Av Brigadeiro Faria Lima",
      "number": "2391",
      "neighborhood": "Jardins",
      "city": "SÃO PAULO",
      "uf": "SP",
      "complement": "",
      "postal_code": "00000-000"
    },
    "phones": [
      {
        "international_dial_code": "55",
        "area_code": "11",
        "number": "00000-0000",
        "type": "mobile"
      },
      {
        "international_dial_code": "55",
        "area_code": "11",
        "number": "00000-0000",
        "type": "residential"
      }
    ]
  },
  "coverages": [
    {
      "description": "S/ PROTEÇÃO AMERICAN PLATINUM",
      "price": 0
    },
    {
      "description": "PROTEÇÃO OCUPANTES E TERCEIROS",
      "price": 1668
    }
  ],
  "billing": {
    "name": "Agência AAA",
    "document_number": "00.000.000/0001-00",
    "voucher_type": "ABCD75",
    "voucher_description": "Pagamento pela agência"
  },
  "rental_price": 43300,
  "extra_hours": 0,
  "extra_hours_price": 0,
  "discount": 0,
  "prepayment_discount": 100,
  "extra_kms": 0,
  "extra_kms_price": 0,
  "third_party_coverage_price": 1490,
  "coverage_price": 0,
  "additional_driver_price": 1000,
  "driver_service_price": 1000,
  "additional_expenses": 1000,
  "devolution_fee": 0,
  "administration_fee": 5374,
  "discount_partial_coverage": 50,
  "final_price": 50165,
  "pre_authorization_amount": 0,
  "coverage_deductible_amount": 0
}
```

Todas as trocas de informação de uma Reservation utilizam a seguinte definição para este objeto. Em alguns casos, para facilitar a implementação e diminuir o fluxo de dados entre as partes, algumas informações poderão ser omitidas.

| nome | tipo | descrição |
| :----: | :----: | --------- |
| **id** | string | Identificador da requisição de análise no sistema do cliente. **É essencial que este número seja único para cada análise.** *(obrigatório)* |
| reservation_code | string | Identificador da Reserva no sistema do cliente. - Este campo é opcional e pode ser definido utilizando o método PUT |
| **reservation_date** | DateTime | Data e Hora com fuso-horário do momento em que ocorreu a reserva para este aluguel. *(obrigatório)* |
| **rental_agreement_date** | DateTime | Data e Hora com fuso-horário da retirada do veículo do aluguel. *(obrigatório)* |
| **car_rental_estimated_final_date** | DateTime | Data e Hora com fuso-horário de quando o carro deve ser resolvido. *(obrigatório)* |
| **rental_store** | *store* | Loja onde o carro será retirado. *(obrigatório)* |
| rental_store_group | *store* | Filial da loja onde o carro será retirado |
| rental_store_type | *store* | Tipo da loja onde o carro será retirado |
| **devolution_store** | *store* | Loja onde o carro será devolvido, pode ou não ser a mesma loja de retirada. *(obrigatório)* |
| reservation_channel | string | Canal pelo qual foi feito a reserva para este aluguel. |
| **sales_channel** | string | Canal de vendas pelo qual a reserva foi realizada (ex.: PARCERIA MASTERCARD). *(obrigatório)* |
| **car** | *car* | Carro que será retirado. *(obrigatório)* |
| **client** | *client* | Objeto que carrega as informações do cliente que fará a retirada do veículo. *(obrigatório)* |
| **coverages** | List of *coverage* | Lista de objetos coverage que descrevem as coberturas de seguro contratadas pelo cliente. *(obrigatório)* |
| billing | *billing* | Objeto que descreve os detalhes da pessoa ou empresa responsável pelo pagamento do aluguel. |
| **rental_price** | integer | Preço do aluguel, em centavos. *(obrigatório)* |
| **extra_hours** | integer | Quantidade de horas extras contratadas. *(obrigatório)* |
| **extra_hours_price** | integer | Preço das horas extras contratadas, em centavos. *(obrigatório)* |
| **discount** | inteiro | Desconto concedido por quaisquer motivos, em centavos. *(obrigatório)* |
| **prepayment_discount** | inteiro | Desconto por pagamento antecipado. *(obrigatório)* |
| **extra_kms** | integer | Quantidade de kilômetros extras contratados. *(obrigatório)* |
| **extra_kms_price** | integer | Preço de kilômetros extras contratados, em centavos. *(obrigatório)* |
| **third_party_coverage_price** | integer | Preço do seguro de terceiros, em centavos. *(obrigatório)* |
| coverage_price | integer | Preço do seguro contratado, em centavos. |
| **additional_driver_price** | integer | Preço total do(s) motoristas adicionais contratados, em centavos. *(obrigatório)* |
| **driver_service_price** | integer | Preço total do serviço de motorista contratado, em centavos. *(obrigatório)* |
| **additional_expenses** | integer | Despesas adicionais, em centavos. *(obrigatório)* |
| **devolution_fee** | integer | Preço da taxa de devolução, em centavos. *(obrigatório)* |
| **administration_fee** | integer | Preço da taxa de administração, em centavos. *(obrigatório)* |
| **discount_partial_coverage** | integer | Desconto de proteção parcial, em centavos. *(obrigatório)* |
| **final_price** | integer | Preço final do aluguel, em centavos. *(obrigatório)* |
| **pre_authorization_amount** | integer | Valor da pré-autorização, em centavos. *(obrigatório)* |
| **coverage_deductible_amount** | integer | Valor dedutível da cobertura, em centavos. *(obrigatório)* |

## Enviar uma Reserva

Exemplo de Request:

```json
{
  "id": "bca6268e-918a-4658-9161-a10b00a631ab",
  ...
}
```

Exemplo de Retorno:

```json
{
  "reservation_key": "bca6268e-918a-4658-9161-a10b00a631ab",
  "fraud_status": "automatically_approved",
  "pre_authorization_amount": 10000
}
```

Para realizar a avaliação de uma reserva, basta enviar um objeto do tipo Reservation ao seguinte endpoint:

`POST https://api.caas.qitech.app/car_rental/reservation`

Além do status do retorno, também é retornado, caso haja, o valor da pré autorização desejada. Caso nenhuma majoração de pré autorização seja identificada, o valor retornado é nulo e não deve ser utilizado.

## Definir o código de uma Reserva

A QI Tech possibilita a definição do código da reserva após a análise inicial. Isto é útil em alguns fluxos operacionais. Nestes casos, basta realizar um PUT no endpoint a seguir, com o código da reserva definido no corpo:

`PUT https://api.caas.qitech.app/car_rental/reservation/{reservation_id}`

:::note
Caso o código da reserva tenha sido definido anteriormente, na requisição de POST ou utilizando um PUT, não é possível redefinir o código da reserva. Neste caso, a API retornará 409 - Conflito.
:::

```json
{
  "reservation_code": "123456789"
}
```

## Recuperar uma Reserva

A fim de recuperar uma Reserva específica, basta realizar uma requisição GET. O resultado retornado é o json mais atualizado da Reserva em questão. Caso este identificador não esteja relacionado a nenhum objeto, o HTTP Status 404 é retornado.

`GET https://api.caas.qitech.app/car_rental/reservation/{reservation_id}`

```shell
curl "https://api.caas.qitech.app/car_rental/reservation/{reservation_id}"
  -H "Authorization: TESTETESTETESTE"
```

---

# Reservation-v2

URL: /documentation/caas/car_rental/reservation_v2

Esta seção diz respeito às informações necessárias para o fluxo de análise de fraude primariamente na reserva.

Ao realizar a reserva de um veículo, o locatário dá início ao seu processo de anti-fraude. Os dados enviados deverão ser os dados finais da reserva, que não serão alterados. Isto é importante para garantir dois pontos:

- Consistência dos dados na base de dados do Antifraude
- Avaliação realista do risco

O processo de análise consiste em enviar uma Reservation no endpoint adequado e esperar a resposta. Existem oito resultados possíveis, devolvido na flag **fraud_status**:

| Resultado | Descrição |
| :---------: | --------- |
| Aprovado Automaticamente | Recomenda-se que este aluguel seja aprovado |
| Negado Automaticamente | Recomenda-se que este aluguel seja reprovado |
| Derivado para análise manual | Nossas regras ou modelos não estão confiantes da decisão e decidiram enviar este aluguel para a análise manual. |
| Aprovado Manualmente | Após análise manual, o analista escolheu aprovar o aluguel |
| Reprovado Manualmente | Após análise manual, o analista escolheu reprovar o aluguel |
| Desafiado Manualmente | Após análise manual, o analista retorna para a loja que a CNH e/ou Selfie estão incorretas e/ou com baixa qualidade |
| Pendente | As consultas estão demorando mais do que o esperado, este aluguel entrou em uma fila de análise automática e será respondido por meio de Webhook |
| Não analisado | A consulta foi enviada com a flag de análise falsa, o que significa que nossos sistemas não deverão retornar parecer |

### Dinâmica dos Status

Ao recuperar um objeto do tipo Reservation os status estão disponíveis. Além dos status, um histórico de modificações também são retornados para que possa ser consultado no futuro. Estas modificações são entituladas events e possuem, além do novo status, as datas de modificação.

### Dinâmica dos Status - **fraud_status**

O status **fraud_status** indica o status da decisão do motor de fraude e possui uma máquina de estados bastante simples:

- `created`
- `automatically_approved`
- `automatically_reproved`
- `in_manual_analysis`
- `manually_approved`
- `manually_reproved`
- `pending`
- `not_analyzed`

## Definição do Objeto

```json
{
  "id": "bca6268e-918a-4658-9161-a10b00a631ab",
  "reservation_code": "211034324",
  "reservation_date": "2024-03-19T10:30:00-03:00",
  "rental_agreement_date": "2024-03-25T10:30:00-03:00",
  "car_rental_estimated_final_date":  "2024-03-30T10:28:00-03:00",
  "channel": "reservation_central",
  "sales_channel" : "PARCERIA TELEFONICA",
  "rental_store": "SAOP",
  "rental_store_group": "GSP",
  "rental_store_type": "LOJA DE RUA",
  "devolution_store": "SAOP",
  "risky_antecedence": true,
  "car": {
    "model_group": "SV",
    "rental_daily_price" : 48496
  },
  "client": {
    "type": "natural_person",
    "segment": "ota",
    "document_number": "123.456.789-00",
    "name": "John Sample",
    "gender": "female",
    "birthdate": "2001-01-15",
    "mother_name": "Mary Sample",
    "email": "john.sample@sample.com.br",
    "allowed_information_on_email": true,
    "face_picture": "c77d1925-0e72-4634-8393-395dbbce498d",
    "additional_pictures": [
      "718b8caa-8ef5-446c-b101-2dbf6c7e401f",
      "9c67f365-1427-4889-b963-d3729d437ff3",
      "8006f82c-3a80-4371-914e-e88c91507711",
      "42c6909e-51aa-4b6d-972f-f4684a047993",
      "b7a88947-96bd-4557-81e9-a69a3c84f428"
    ],
    "total_rents": 6,
    "fidelity_points": 1200,
    "documents": {
      "rg": {
        "document_number": "00000000",
        "issuer": "SSP"
      },
      "cnh": {
        "document_number": "000000000",
        "security_code": "00000",
        "first_issuance": "2015-07-20",
        "expiration_date": "2030-07-26",
        "state": "SP"
      }
    },
    "residential_address": {
      "street": "Av Brigadeiro Faria Lima",
      "number": "2391",
      "neighborhood": "Jardins",
      "city": "SÃO PAULO",
      "uf": "SP",
      "complement": "",
      "postal_code": "00000-000"
    },
    "commercial_address": {
      "street": "Av Brigadeiro Faria Lima",
      "number": "2391",
      "neighborhood": "Jardins",
      "city": "SÃO PAULO",
      "uf": "SP",
      "complement": "",
      "postal_code": "00000-000"
    },
    "phones": [
      {
        "international_dial_code": "55",
        "area_code": "11",
        "number": "00000-0000",
        "type": "mobile"
      },
      {
        "international_dial_code": "55",
        "area_code": "11",
        "number": "00000-0000",
        "type": "residential"
      }
    ]
  },
  "coverages": [
    {
      "description": "S/ PROTEÇÃO AMERICAN PLATINUM",
      "price": 0
    },
    {
      "description": "PROTEÇÃO OCUPANTES E TERCEIROS",
      "price": 1668
    }
  ],
  "billing": {
    "name": "Agência AAA",
    "document_number": "00.000.000/0001-00",
    "voucher_type": "ABCD75",
    "voucher_description": "Pagamento pela agência"
  },
  "fare_name": "MENSAL - 2000KM - PRÓ-RATA",
  "rental_price": 43300,
  "extra_hours": 0,
  "extra_hours_price": 0,
  "discount": 0,
  "prepayment_discount": 100,
  "extra_kms": 0,
  "extra_kms_price": 0,
  "third_party_coverage_price": 1490,
  "coverage_price": 0,
  "additional_driver_price": 1000,
  "driver_service_price": 1000,
  "additional_expenses": 1000,
  "devolution_fee": 0,
  "administration_fee": 5374,
  "discount_partial_coverage": 50,
  "final_price": 50165,
  "pre_authorization_amount": 0,
  "coverage_deductible_amount": 0
}
```

Todas as trocas de informação de uma Reservation utilizam a seguinte definição para este objeto. Em alguns casos, para facilitar a implementação e diminuir o fluxo de dados entre as partes, algumas informações poderão ser omitidas.

| nome | tipo | descrição |
| :----: | :----: | --------- |
| **id** | string | Identificador da requisição de análise no sistema do cliente. **É essencial que este número seja único para cada análise.** *(obrigatório)* |
| reservation_code | string | Identificador da Reserva no sistema do cliente. - Este campo é opcional e pode ser definido utilizando o método PUT. |
| **reservation_date** | DateTime | Data e Hora com fuso-horário do momento em que ocorreu a reserva para este aluguel. *(obrigatório)* |
| **car_rental_estimated_final_date** | DateTime | Data e Hora com fuso-horário de quando o carro deve ser resolvido. *(obrigatório)* |
| **rental_store** | *store* | Loja onde o carro será retirado. *(obrigatório)* |
| rental_store_group | *store* | Filial da loja onde o carro será retirado |
| rental_store_type | *store* | Tipo da loja onde o carro será retirado |
| **devolution_store** | *store* | Loja onde o carro será devolvido, pode ou não ser a mesma loja de retirada. *(obrigatório)* |
| reservation_channel | string | Canal pelo qual foi feito a reserva para este aluguel. |
| **sales_channel** | string | Canal de vendas pelo qual a reserva foi realizada (ex.: PARCERIA MASTERCARD). *(obrigatório)* |
| **car** | *car* | Objeto que carrega as informações do veículo sendo reservado. *(obrigatório)* |
| **client** | *client* | Objeto que carrega as informações do cliente que fará a retirada do veículo. *(obrigatório)* |
| **coverages** | List of *coverage* | Lista de objetos coverage que descrevem as coberturas de seguro contratadas pelo cliente. *(obrigatório)* |
| **billing** | *billing* | Objeto que descreve os detalhes da pessoa ou empresa responsável pelo pagamento do aluguel. *(obrigatório)* |
| **rental_price** | integer | Preço do aluguel, em centavos. *(obrigatório)* |
| **extra_hours** | integer | Quantidade de horas extras contratadas. *(obrigatório)* |
| **extra_hours_price** | integer | Preço das horas extras contratadas, em centavos. *(obrigatório)* |
| **discount** | inteiro | Desconto concedido por quaisquer motivos, em centavos. *(obrigatório)* |
| **prepayment_discount** | inteiro | Desconto por pagamento antecipado. *(obrigatório)* |
| **extra_kms** | integer | Quantidade de kilômetros extras contratados. *(obrigatório)* |
| **extra_kms_price** | integer | Preço de kilômetros extras contratados, em centavos. *(obrigatório)* |
| **third_party_coverage_price** | integer | Preço do seguro de terceiros, em centavos. *(obrigatório)* |
| coverage_price | integer | Preço do seguro contratado, em centavos. |
| **additional_driver_price** | integer | Preço total do(s) motoristas adicionais contratados, em centavos. *(obrigatório)* |
| **driver_service_price** | integer | Preço total do serviço de motorista contratado, em centavos. *(obrigatório)* |
| **additional_expenses** | integer | Despesas adicionais, em centavos. *(obrigatório)* |
| **devolution_fee** | integer | Preço da taxa de devolução, em centavos. *(obrigatório)* |
| **administration_fee** | integer | Preço da taxa de administração, em centavos. *(obrigatório)* |
| **discount_partial_coverage** | integer | Desconto de proteção parcial, em centavos. *(obrigatório)* |
| **final_price** | integer | Preço final do aluguel, em centavos. *(obrigatório)* |
| **pre_authorization_amount** | integer | Valor da pré-autorização, em centavos. *(obrigatório)* |
| **coverage_deductible_amount** | integer | Valor dedutível da cobertura, em centavos. *(obrigatório)* |

## Enviar uma Reserva

Exemplo de Request:

```json
{
  "id": "bca6268e-918a-4658-9161-a10b00a631ab",
  "reservation_code": "211034324",
  ...
}
```

Exemplo de Retorno:

```json
{
  "reservation_key": "bca6268e-918a-4658-9161-a10b00a631ab",
  "fraud_status": "automatically_approved",
  "pre_authorization_amount": 10000
}
```

Para realizar a avaliação de uma reserva, basta enviar um objeto do tipo Reservation ao seguinte endpoint:

`POST https://api.caas.qitech.app/car_rental/reservation`

Além do status do retorno, também é retornado, caso haja, o valor da pré autorização desejada. Caso nenhuma majoração de pré autorização seja identificada, o valor retornado é nulo e não deve ser utilizado.

## Definir o código de uma Reserva

A QI Tech possibilita a definição do código da reserva após a análise inicial. Isto é útil em alguns fluxos operacionais. Nestes casos, basta realizar um PUT no endpoint a seguir, com o código da reserva definido no corpo:

`PUT https://api.caas.qitech.app/car_rental/reservation/{reservation_id}`

:::note
Caso o código da reserva tenha sido definido anteriormente, na requisição de POST ou utilizando um PUT, não é possível redefinir o código da reserva. Neste caso, a API retornará 409 - Conflito.
:::

```json
{
  "reservation_code": "123456789"
}
```

## Recuperar uma Reserva

A fim de recuperar uma Reserva específica, basta realizar uma requisição GET. O resultado retornado é o json mais atualizado da Reserva em questão. Caso este identificador não esteja relacionado a nenhum objeto, o HTTP Status 404 é retornado.

`GET https://api.caas.qitech.app/car_rental/reservation/{reservation_id}`

```shell
curl "https://api.caas.qitech.app/car_rental/reservation/{reservation_id}"
  -H "Authorization: TESTETESTETESTE"
```

---

# Padrões

URL: /documentation/caas/car_rental/standards

Para facilitar a integração e garantir a integridade da informação, foram definidos alguns padrões que são seguidos em toda a API.

## Valores Monetários

Exemplos:

```
10000
12345
98741
1223
1
0
```

As APIs assumem que todos os valores monetários enviados são em Reais Brasileiros. Os valores devem ser enviados como inteiro em centavos.

## Data e Hora com Fuso Horário

Alguns exemplos:

```
2019-10-15T22:35:12-03:00
2018-05-01T13:32:11+00:00
2019-05-01T00:00:00+00:00
```

É representada conforme a ISO 8601. Neste caso, o fuso-horário é colocado logo após o horário e deve representar o fuso do local onde aquele dado será válido. Por exemplo, se um aluguel estiver marcado para começar às 09:30 no aeroporto de Brasília, o horário enviado deverá ser representado por 09:30-03:00, se o aluguel estiver marcado para começar às 09:30 em Manaus, deverá ser representado por 09:30-04:00.

A máscara utilizada para validação é a seguinte:

`YYYY-MM-ddThh:mm:ss±hh:mm`

## Data e Hora sem Fuso Horário

Alguns exemplos:

```
2019-10-15T22:35:12Z
2018-05-01T13:32:11Z
2019-05-01T00:00:00Z
```

É representada conforme a ISO 8601. Dados que independem de fuso-horário deverão ser enviados sem ele, sempre em UTC, com a letra Z indicando que este dado está em UTC. O seguinte formato, portanto, será validado:

`YYYY-MM-ddThh:mm:ssZ`

## Data

Alguns exemplos:

```
2019-10-15
2019-01-01
2017-03-20
```

No caso de campos que recebem somente data, uma data de nascimento, por exemplo, somente a data, sem nenhum horário deve ser enviada com o seguinte formato:

`YYYY-MM-dd`

## Documentos

Uma vez que os números de documento são bastante variados e muitos deles possuem caracteres que não se enquadram como numéricos, definem-se todos os números de documento como string. Outro bom motivo para defini-los como string é evitar que os zeros à esquerda desapareçam. Documentos previstos nesta página possuem uma máscara bem definida e estarão sujeitos a validação. O restante dos documentos, como RG, dada sua falta de padronização, não serão validados.

## CPF

Exemplos de CPFs válidos contra a máscara definida:

```
123.456.789-12
321.987.543-23
111.283.333-00
```

Exemplos de CPFs inválidos contra a máscara definida:

```
8.577.477-8
08.104.627/0001-23
123.456.789-1
23.456.789-01
```

O CPF é sempre definido como uma string e será validado contra a máscara:

`###.###.###-##`

## CNPJ

Exemplos de CNPJs válidos contra a máscara definida:

```
08.104.627/0001-02
01.079.210/0114-67
32.402.502/0001-35
```

Exemplos de CNPJs inválidos contra a máscara definida:

```
8.577.477-8
123.456.789-12
321.987.543-23
32.402.502/0001-3
032.402.502/0001-3
```

O CNPJ é sempre definido como uma string e será validado contra a máscara:

`##.###.###/####-##`

---

# Webhook

URL: /documentation/caas/car_rental/webhook

Webhook

Atualizações no status de fraude (Para RentalAgreements que sejam derivados para análise manual ou que sejam respondidos como Pendente), são notificados por meio de Webhook. Para tanto, é necessário, por meio da equipe do [suporte](mailto:suporte.caas@qitech.com.br), configurar um endereço do endpoint por onde vamos notificar as atualizações e também um *secret_token* que será utilizado para assinar a requisição.

O cliente pode, apesar de não recomendável, também utilizar a técnica de [polling](https://en.wikipedia.org/wiki/Polling_(computer_science)). Neste caso, basta não configurar o endpoint de webhook e utilizar os endpoints de recuperação de RentalAgreement para proceder com o polling.

## Assinatura do Webhook

## Requisição

Exemplo de requisição:

```json
{
  "rental_agreement_id": "123456",
  "fraud_status": "automatically_approved",
  "upgrade_status": "automatically_approved",
  "event_date": "2019-10-01T10:37:25-03:00"
}
```

A requisição possui o formato acima e notifica a mudança no status de fraude.

## Retentativas

A notificação é considerada realizada quando recebe como resposta um HTTP Status 200. Caso as notificações falhem, serão feitas retentativas, com os seguintes intervalos, até que um 200 seja retornado ou as tentativas terminem:

- 10 segundos
- 30 segundos
- 60 segundos
- 120 segundos
- 120 segundos
- 3600 segundos
- 7200 segundos
- 36000 segundos