> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tangoanalytics.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Total approved budget inbound

# Tango Total Approved Budget Inbound API

> Generated from `Tango Total Approved Budget Inbound API Integration Design Specification V0.4.docx` in SharePoint folder `04 Projects Integrations`.
> OAS spec: [`total-approved-budget-inbound.yaml`](./total-approved-budget-inbound.yaml)

## Overview

Async REST API for posting approved budget totals into Tango. The same payload covers both **Project** and **Lease** budgets — populated identifier fields determine which branch applies. Async two-call pattern with `gu_id`.

**Owner:** Tango Analytics
**Spec version:** 0.4
**Status:** Draft (auto-generated from design doc — needs review)

## Base URLs

| Environment | URL |
| - | - |
| Production | `https://api.tangoanalytics.com` |
| Test (SIT/UAT) | `https://testapi.tangoanalytics.com` |

## Authentication

`x-client` and `x-api-key` headers, required on every call.

## Endpoints

| Method | Path | Summary |
| - | - | - |
| PUT | `/v1/projectmgmt/batch/budgets` | Submit budget records (async). |
| GET | `/v1/batch/status?gu_id=...` | Poll processing status. |

### `PUT /v1/projectmgmt/batch/budgets`

**Request — project mode**

```json theme={null}
{
  "records": [
    {
      "header_created_date": "03/20/2012",
      "header_last_updated_date": "03/20/2025",
      "header_requested_by": "John Doe",
      "header_status": "APPROVED",
      "lease_num": "",
      "project_num": "A64390",
      "line_item_seq": 10,
      "client_ref_num": 429,
      "total": 1000000
    }
  ]
}
```

**Request — lease mode**

```json theme={null}
{
  "records": [
    {
      "header_created_date": "03/20/2012",
      "header_last_updated_date": "03/20/2025",
      "header_requested_by": "John Doe",
      "header_status": "APPROVED",
      "lease_num": "L89096",
      "project_num": "",
      "line_item_seq": "",
      "client_ref_num": "",
      "total": 1440000
    }
  ]
}
```

**Response — 200 OK**

```json theme={null}
{
  "status": "OK",
  "status_message": "",
  "gu_id": "721c54c4-c7aa-4fa1-8fdfd6-c0cee161694d"
}
```

### `GET /v1/batch/status?gu_id=...`

Standard three-shape response (`PROCESSING` / `COMPLETED` / `ERROR`).

## Integration logic

* Project mode: budget template must be applied and available; budget rows are populated against the total-approved budget line.
* `client_ref_num` is the client-specific unique reference to identify a budget line. Either `client_ref_num` OR `line_item_seq` must be sent.
* If project baseline versioning is enabled, the data updates the draft baseline; once approved, a new baseline is created.
* After the initial payload, subsequent `total` values are **added** to the existing amount (cumulative, not replacement).
* Once a total is loaded, the project status is set to `Approved`.
* Lease mode: the total approved rent amount can be loaded for the lease.

## Data model (per-mode required flags)

| Field | Type | Required (Project) | Required (Lease) | Notes |
| - | - | - | - | - |
| `header_created_date` | Date `MM/DD/YYYY` | ✅ | – | |
| `header_last_updated_date` | Date `MM/DD/YYYY` | ✅ | ✅ | |
| `header_requested_by` | Varchar | – | – | |
| `header_status` | Varchar | ✅ | ✅ | Only `APPROVED` accepted |
| `lease_num` | Varchar | – | ✅ | One of `lease_num` / `project_num` must be non-empty |
| `project_num` | Varchar | ✅ | – | One of `lease_num` / `project_num` must be non-empty |
| `line_item_seq` | Number | ✅ (one-of) | – | Either `line_item_seq` or `client_ref_num`; must be unique within project when sent |
| `client_ref_num` | Number | ✅ (one-of) | – | Either `client_ref_num` or `line_item_seq`; unique within project when sent |
| `total` | Number | ✅ | ✅ | Aggregate total per project/lease (cumulative on update) |

## Validations

| # | Condition | Error message |
| - | - | - |
| 1 | `header_created_date` null | `header_created_date is missing or empty` |
| 2 | `header_created_date` not `MM/DD/YYYY` | `header_created_date does not match expected format` |
| 3 | `header_last_updated_date` null | `header_last_updated_date is missing or empty` |
| 4 | `header_last_updated_date` not `MM/DD/YYYY` | `header_last_updated_date does not match expected format` |
| 5 | `header_status` null | `header_status is missing or empty` |
| 6 | `header_status != APPROVED` | `header_status is invalid` |
| 7 | Both `lease_num` and `project_num` null | `Either lease_num or project_num is required` |
| 8 | `lease_num` not valid | `lease_num does not exist` |
| 9 | `project_num` not valid | `project_num does not exist` |
| 10 | `total` null | `total is missing or empty` |
| 11 | `total` not numeric | `total is not a valid number` |
| 12 | `client_ref_num` null | `client_ref_num is missing or empty` |
| 13 | `client_ref_num` not numeric | `client_ref_num is not a valid number` |

## Open Questions / Assumptions

* [ ] **OAS 3.1 cannot natively express the dual-mode required-field matrix** — the schema enforces only the common baseline; runtime validation must add Project-mode and Lease-mode rules.
* [ ] **Validation #12** says `client_ref_num is missing or empty` unconditionally but the data-mapping says either `client_ref_num` OR `line_item_seq` is acceptable. Treating the validation as Project-mode-conditional based on data-mapping.
* [ ] **`header_status` enum**: only `APPROVED` is listed as accepted; modeled as a single-value enum.
* [ ] **No explicit response for synchronous validation errors** at the PUT endpoint — assumed errors land in the polled status response.
* [ ] **Sample value of `line_item_seq`** is sent as `""` in lease mode (empty string in a number field); modeled as `oneOf number | empty string`.
* [ ] **Baseline versioning side-effect**: doc mentions a new baseline is created on approval — out of scope for the request schema but flagged so consumers know about the state change.

## Changelog

| Ver | Date | Description | Author |
| - | - | - | - |
| 0.1 | 03/20/2025 | Initial Draft | Jasmin Thasleem |
| 0.2 | 06/23/2025 | Updated Integration Logic and URLs | Rahma Ouedraogo |
| 0.3 | 01/20/2026 | Updated Integration Logic | Jasmin Thasleem |
| 0.4 | 04/23/2026 | Updated API Architecture | Jasmin Thasleem |
