> ## 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.

# Contracts inbound

# Tango Contracts Inbound API

> Generated from `Tango Contracts Inbound API Integration Design Specification V0.4.docx` in SharePoint folder `04 Projects Integrations`.
> OAS spec: [`contracts-inbound.yaml`](./contracts-inbound.yaml)

## Overview

Async REST API for posting contract records from a client system into Tango. The client `PUT`s a batch of records; Tango returns an `OK/Error` envelope plus a `gu_id`, and the client polls the Status endpoint with that `gu_id` until processing finishes.

**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

Two required headers on every call:

| Header | Purpose |
| - | - |
| `x-client` | Tango-issued client identifier |
| `x-api-key` | Tango-issued API key |

## Endpoints

| Method | Path | Summary |
| - | - | - |
| PUT | `/v1/suppliermgmt/batch/agreements` | Submit a batch of contract records (async). |
| GET | `/v1/batch/status?gu_id=...` | Poll processing status by gu\_id. |

### `PUT /v1/suppliermgmt/batch/agreements`

Submit a `records` array. Tango is async — the response only confirms acceptance.

**Request (excerpt)**

```json theme={null}
{
  "records": [
    {
      "contract_number": "104267-13-B-0005",
      "contract_name": "104267-13-B-0005",
      "supplier_site_number": "670234-1",
      "contract_start_date": "06/11/2013",
      "contract_end_date": "03/20/2026",
      "contract_amount": 5000000,
      "modification_amount": 70241015.18,
      "max_contract_amount": 250000000,
      "contract_status": "A",
      "description": "Contract for reconstruction"
    }
  ]
}
```

**Response — 200 OK**

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

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

Three possible response shapes:

```json theme={null}
{ "status": "PROCESSING" }
```

```json theme={null}
{ "status": "COMPLETED", "total_records": 2, "errors": null }
```

```json theme={null}
{
  "status": "ERROR",
  "total_records": 1,
  "errors": [
    { "record_index": 1, "record_key": "13001-001", "error": "contract_number is missing or empty" }
  ]
}
```

## Integration logic

* Upsert key: `(supplier_site_number, contract_number)`.
* `contract_amount` is set on creation and is immutable afterwards.
* Updates to total flow through `modification_amount`, which is **added** to the existing modification amount (cumulative, not replacement).
* `supplier_site_number` must reference an existing supplier site in Tango — non-existent values are rejected.

## Data model (required fields)

| Field | Type | Required | Notes |
| - | - | - | - |
| `contract_number` | Varchar | ✅ | Upsert key (with supplier\_site\_number). |
| `contract_name` | Varchar | ✅ | |
| `supplier_site_number` | Varchar | ✅ | Must exist in Tango. |
| `contract_start_date` | Date | ✅ | `MM/DD/YYYY`. |
| `contract_end_date` | Date | ✅ | `MM/DD/YYYY`. |
| `contract_amount` | Number | ✅ | Immutable after create. |
| `modification_amount` | Number | – | Cumulative. |
| `contract_status` | Varchar | – | Sample shows `"A"`. |
| `max_contract_amount` | Number | – | |
| `description` | Varchar | – | |
| `c_ext_attr01..10` | Varchar | – | Client extension attributes. |
| `c_ext_lov01..10` | Varchar | – | Client extension lookups. |
| `d_ext_attr01..10` | Date `MM/DD/YYYY` | – | Client extension dates. |
| `n_ext_attr01..10` | Number | – | Client extension numerics. |

## Validations (per source doc)

| # | Condition | Error message |
| - | - | - |
| 1 | `contract_number` null | `contract_number is missing or empty` |
| 2 | `contract_name` null | `contract_name is missing or empty` |
| 3 | `supplier_site_number` null | `supplier_site_number is missing or empty` |
| 4 | `supplier_site_number` not valid | `supplier_site_number does not exist` |
| 5 | `contract_start_date` null | `contract_start_date is missing or empty` |
| 6 | `contract_start_date` not `MM/DD/YYYY` | `contract_start_date does not match expected format` |
| 7 | `contract_end_date` null | `contract_end_date is missing or empty` |
| 8 | `contract_end_date` not `MM/DD/YYYY` | `contract_end_date does not match expected format` |
| 9 | `contract_amount` null | `contract_amount is missing or empty` |
| 10 | `contract_amount` not numeric | `Contract_amount is not a valid number` |
| 11 | User-defined dates not `MM/DD/YYYY` | `<>  does not match expected format` |
| 12 | User-defined lookup not valid | `<>  does not match lookup value` |
| 13 | User-defined number not numeric | `<>  is not a valid number` |
| 14 | `modification_amount` not numeric | `modification_amount is not a valid number` |
| 15 | `tot_contract_amount` not numeric | `tot_contract_amount is not a valid number` |
| 16 | `status` not in lookup | `status does not match lookup value` |

## Open Questions / Assumptions

* [ ] `contract_status` accepted values are not enumerated; sample shows `"A"` only. Confirm the full enum (Active, Closed, etc.).
* [ ] Validation #15 references `tot_contract_amount` but the field is not in the schema — confirm whether this is the same as `max_contract_amount` or a different field.
* [ ] Date strings use `MM/DD/YYYY` literal; not ISO 8601. Confirm this is intentional vs. a doc convention.
* [ ] Lookup values for `contract_status` and `c_ext_lov01..10` are marked `<TBD>` in the Appendix.
* [ ] No explicit error response shape is defined for synchronous validation failures at the PUT endpoint — assumed errors come back via the polled status endpoint.

## Changelog (from source doc)

| Ver | Date | Description | Author |
| - | - | - | - |
| 0.1 | 03/18/2025 | Initial Draft | Jasmin Thasleem |
| 0.2 | 03/21/2025 | Updated Validations | Jasmin Thasleem |
| 0.3 | 12/18/2025 | Updated Request Body and Data Mapping | Jasmin Thasleem |
| 0.4 | 04/23/2026 | Updated API Architecture | Jasmin Thasleem |
