> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/azfar-imtiaz/PayPulse-Cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Ingest rental invoices

> Fetch all rental invoice PDFs from the user's connected Gmail account and upload them to S3.

## Authentication

All requests to this endpoint must include a valid JWT in the `Authorization` header.

```
Authorization: Bearer <token>
```

## Path parameters

<ParamField path="type" type="string" required>
  The invoice type. Must be `rental` for this endpoint.
</ParamField>

## What this endpoint does

This endpoint connects to the user's Gmail account via the stored OAuth tokens, searches for rental invoice emails matching the configured sender and subject, and uploads any previously unseen invoice PDF attachments to S3. It skips invoices for months that have already been processed.

The Gmail account must be connected before calling this endpoint. See [Store Gmail tokens](/api-reference/auth/store-gmail-tokens).

## Response

<ResponseField name="message" type="string">
  A human-readable confirmation message. Example: `"Rental invoices ingested successfully!"` or `"No rental invoices found for this user."`
</ResponseField>

<ResponseField name="code" type="number">
  HTTP status code. `200` on success.
</ResponseField>

<ResponseField name="data" type="object | null">
  `null` when no new invoices were found. Otherwise contains the fields below.

  <Expandable title="properties" defaultOpen>
    <ResponseField name="invoiceCount" type="number">
      Number of new rental invoices ingested during this request.
    </ResponseField>
  </Expandable>
</ResponseField>

## Error responses

| Status | Error code              | Description                                                                     |
| ------ | ----------------------- | ------------------------------------------------------------------------------- |
| `400`  | `INVALID_JSON`          | The request body is not valid JSON.                                             |
| `400`  | `MISSING_FIELDS`        | A required key is missing from the request.                                     |
| `401`  | `INVALID_CREDENTIALS`   | The `Authorization` header is missing or the OAuth token is invalid.            |
| `401`  | `TOKEN_EXPIRED`         | The JWT has expired.                                                            |
| `502`  | `DEPENDENCY_FAILURE`    | The Gmail API returned an error.                                                |
| `502`  | `GMAIL_TOKEN_EXPIRED`   | The Gmail OAuth refresh token has expired and the account must be re-connected. |
| `500`  | `INTERNAL_SERVER_ERROR` | An unexpected server-side error occurred.                                       |

Error responses follow this structure:

```json theme={null}
{
  "error": {
    "code": "GMAIL_TOKEN_EXPIRED",
    "message": "Gmail account needs to be re-connected"
  }
}
```

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.paypulse.io/v1/invoices/rental/ingest \
    --header 'Authorization: Bearer <token>'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 (invoices found) theme={null}
  {
    "message": "Rental invoices ingested successfully!",
    "code": 200,
    "data": {
      "invoiceCount": 3
    }
  }
  ```

  ```json 200 (no invoices found) theme={null}
  {
    "message": "No rental invoices found for this user.",
    "code": 200,
    "data": null
  }
  ```

  ```json 502 theme={null}
  {
    "error": {
      "code": "GMAIL_TOKEN_EXPIRED",
      "message": "Gmail account needs to be re-connected"
    }
  }
  ```
</ResponseExample>
