intermediate25 minutes
Documents API
REST API for managing compliance documents programmatically
Overview
The Documents API allows you to programmatically manage compliance documents for your company. Upload, retrieve, update, and delete documents that are used in tender applications.
Base URL
Base URL:
All API requests require authentication via Bearer token.
https://api.tenders-sa.org/v1All API requests require authentication via Bearer token.
Authentication
Include your API key in the Authorization header:
Authentication Header
bash
Document Types
The API supports the following document types:
| Type | Description | Expiry Tracking |
|------|-------------|----------------|
|
|
|
|
|
|
|
|
| Type | Description | Expiry Tracking |
|------|-------------|----------------|
|
TAX_CLEARANCE | SARS Tax Clearance Certificate | ✅ ||
CIPC_REGISTRATION | Company Registration Document | ❌ ||
BBBEE_CERTIFICATE | BBBEE Verification Certificate | ✅ ||
COMPANY_PROFILE | Company Profile Document | ❌ ||
FINANCIAL_STATEMENTS | Financial Statements | ❌ ||
INSURANCE_CERTIFICATE | Insurance Certificate | ✅ ||
SAFETY_CERTIFICATE | Safety Certificate | ✅ ||
OTHER | Other Document Types | ⚙️ Optional |Endpoints
List Documents
Retrieve all documents for the authenticated company with optional filtering.
Endpoint:
Query Parameters:
| Parameter | Type | Description |
|-----------|------|-----------|
|
|
|
|
|
Endpoint:
GET /documentsQuery Parameters:
| Parameter | Type | Description |
|-----------|------|-----------|
|
type | string | Filter by document type ||
status | string | Filter by expiry status (valid, expiring, expired) ||
verified | boolean | Filter by verification status ||
page | number | Page number (default: 1) ||
per_page | number | Items per page (default: 20, max: 100) |Response (200 OK)
json
Get All Documents
bash
Filter by Document Type
bash
Python Example
python
Upload Document
Upload a new document to your company's document vault.
Endpoint:
Content-Type:
Form Fields:
| Field | Type | Required | Description |
|-------|------|----------|-----------|
|
|
|
|
File Requirements:
- Maximum size: 10MB
- Supported formats: PDF, DOC, DOCX, JPG, PNG
- Filename should be descriptive
Endpoint:
POST /documentsContent-Type:
multipart/form-dataForm Fields:
| Field | Type | Required | Description |
|-------|------|----------|-----------|
|
file | File | ✅ | Document file (PDF, DOC, DOCX, JPG, PNG) ||
documentType | string | ✅ | Document type enum value ||
expiryDate | string | ❌ | ISO date string (required for certain types) ||
description | string | ❌ | Optional description |File Requirements:
- Maximum size: 10MB
- Supported formats: PDF, DOC, DOCX, JPG, PNG
- Filename should be descriptive
Upload Response (201 Created)
json
Upload with cURL
bash
Python Upload Example
python
Get Single Document
Retrieve detailed information for a specific document.
Endpoint:
Endpoint:
GET /documents/{document_id}Get Document Request
bash
Download Document
Download the actual file content for a document.
Endpoint:
Endpoint:
GET /documents/{document_id}/downloadDownload Request
bash
Update Document
Update document metadata (expiry date, verification status).
Endpoint:
Content-Type:
Request Body:
| Field | Type | Description |
|-------|------|-----------|
|
|
|
Endpoint:
PUT /documents/{document_id}Content-Type:
application/jsonRequest Body:
| Field | Type | Description |
|-------|------|-----------|
|
expiryDate | string | ISO date string ||
verified | boolean | Verification status (admin only) ||
description | string | Document description |Update Expiry Date
bash
Delete Document
Permanently delete a document from your vault.
Endpoint:
Endpoint:
DELETE /documents/{document_id}Delete Request
bash
Deleting a document that's referenced in tender applications will not affect submitted applications, but the document will no longer be available for future applications.
Error Handling
The API uses standard HTTP status codes and returns detailed error information.
Status Codes:
| Status Code | Description |
|-------------|-------------|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Invalid or missing API key |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Document doesn't exist |
| 413 | Payload Too Large - File exceeds 10MB |
| 422 | Unprocessable Entity - Validation errors |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
Status Codes:
| Status Code | Description |
|-------------|-------------|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Invalid or missing API key |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found - Document doesn't exist |
| 413 | Payload Too Large - File exceeds 10MB |
| 422 | Unprocessable Entity - Validation errors |
| 429 | Too Many Requests - Rate limit exceeded |
| 500 | Internal Server Error |
Error Response Format
json
Rate Limiting
API requests are rate limited based on your subscription tier:
| Plan | Rate Limit | Burst Limit |
|------|------------|-------------|
| Starter | 100 requests/hour | 20 requests/minute |
| Professional | 1,000 requests/hour | 100 requests/minute |
| Enterprise | 10,000 requests/hour | 500 requests/minute |
Rate limit information is included in response headers:
| Plan | Rate Limit | Burst Limit |
|------|------------|-------------|
| Starter | 100 requests/hour | 20 requests/minute |
| Professional | 1,000 requests/hour | 100 requests/minute |
| Enterprise | 10,000 requests/hour | 500 requests/minute |
Rate limit information is included in response headers:
Response Headers
bash
SDKs and Libraries
Official SDKs:
- Python:
- Node.js:
- PHP:
Community Libraries:
- Ruby:
- Java: Available on Maven Central
- C#: NuGet package available
- Python:
pip install tenders-sa-python- Node.js:
npm install tenders-sa-node- PHP:
composer require tenders-sa/php-sdkCommunity Libraries:
- Ruby:
gem install tenders_sa- Java: Available on Maven Central
- C#: NuGet package available
Python SDK Example
python
Use the API playground above to test endpoints with your API key before implementing in your application.