Sourced Public API v1
The Sourced API enables ERP systems (such as Calipso, SAP, JD Edwards) to integrate directly with Sourced's procurement platform. Use it to:
- Push purchase requisitions from your ERP into Sourced
- Pull purchase orders back into your ERP once awarded
- Check which requisitions have already been synced
- Monitor the status of your requisitions
The API follows REST conventions, uses JSON for request and response bodies, and authenticates via API keys.
Authentication
All endpoints (except health check) require an API key passed in the header.
API keys are created in the Sourced admin panel under . Each key is shown only once upon creation. Store it securely.
curl -H "X-API-Key: sk_live_abc123..." \
https://api.gosourced.ai/api/v1/requisitionsBase URL
| Environment | Base URL |
|---|---|
| Production | https://api.gosourced.ai |
| Development | https://api-dev.gosourced.ai |
All endpoints are prefixed with .
Rate Limiting
All endpoints are limited to per endpoint. Exceeding this limit returns a response.
For bulk operations, use the batch import endpoint () which accepts up to 100 requisitions per request.
Errors
The API uses standard HTTP status codes. Errors return a JSON body with a field.
{
"detail": "Invalid or revoked API key."
}| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad Request — validation error or malformed body |
| 401 | Unauthorized — missing or invalid API key |
| 404 | Not Found — resource does not exist or is not accessible |
| 422 | Unprocessable Entity — request body failed schema validation |
| 429 | Too Many Requests — rate limit exceeded |
| 500 | Internal Server Error — unexpected error on our side |
Error Examples
{
"detail": "Invalid or revoked API key."
}{
"detail": [
{
"loc": ["body", "requisitions", 0, "items", 0, "quantity"],
"msg": "Input should be greater than 0",
"type": "greater_than"
}
]
}{
"success": false,
"created_count": 2,
"updated_count": 0,
"skipped_count": 0,
"error_count": 1,
"errors": [
{
"index": 2,
"external_id": "REQ-2026-0099",
"error": "Failed to process requisition: duplicate external_line_id within items"
}
],
"requisition_ids": [1234, 1235]
}Note: the endpoint returns even with partial failures. Always check the field and the array to detect per-requisition issues.
Health Check
/api/v1/healthVerify the API is reachable. No authentication required.
curl https://api.gosourced.ai/api/v1/health{
"status": "ok",
"api": "v1"
}Import Requisitions
/api/v1/requisitionsAPI Key RequiredImport one or more purchase requisitions from your ERP. Supports batch import of up to 100 requisitions per request. Uses external_id for deduplication.
Request Body
The body must contain a array with 1 to 100 requisition objects.
Requisition Object
| Field | Type | Required | Description |
|---|---|---|---|
| external_id | string | required | Unique ID in your ERP (deduplication key). Max 250 chars. |
| items | array | required | Line items (1-200 items). See Item schema below. |
| requester_name | string | optional | Name of the person requesting. Max 200 chars. |
| requester_email | string | optional | Email of the requester. Max 200 chars. |
| description | string | optional | Requisition title or summary. Max 500 chars. |
| comments | string | optional | Additional instructions for buyers (HTML supported). Max 15,000 chars. |
| delivery_address | string | optional | Free-text delivery address. Max 500 chars. |
| delivery_address_code | string | optional | Code matching an address configured in Sourced. Max 50 chars. |
| desired_delivery_lead_time_days | integer | optional | Desired lead time in days from PO confirmation. Applied as default to all items. |
| offer_deadline | datetime | optional | Deadline for supplier quotations (ISO 8601). |
| total_estimated_value | float | optional | Total estimated value. Auto-calculated from items if omitted. |
| currency | string | optional | Currency code (e.g., "ARS", "USD"). Defaults to "ARS". Max 10 chars. |
| department_code | string | optional | Department/cost center code (matched against Sourced departments). Max 50 chars. |
| priority_level | string | optional | Priority: "LOW", "MEDIUM", "HIGH", or "CRITICAL". |
| attachments | array | optional | File attachments (max 20). See Attachment schema below. |
| raw_data | object | optional | Arbitrary JSON from your ERP, stored for traceability. |
Item Object
| Field | Type | Required | Description |
|---|---|---|---|
| description | string | required | Item name or description. Max 1,000 chars. |
| quantity | float | required | Required quantity (must be > 0). |
| external_line_id | string | optional | Line ID in your ERP (e.g., "REQ-001-L10"). Returned in POs for traceability. Max 100 chars. |
| unit_of_measure | string | optional | UOM code (e.g., "KG", "EA", "LT", "M", "UN"). Matched against your org catalog. Max 50 chars. |
| target_price | float | optional | Target/budget price per unit. |
| estimated_price | float | optional | Estimated total price for this line. |
| currency | string | optional | Currency for prices (e.g., "ARS", "USD"). Max 10 chars. |
| category | string | optional | Category from your ERP. Max 200 chars. |
| material_code | string | optional | Material/part code in your ERP (e.g., SAP material code). Max 100 chars. |
| specifications | object | optional | Technical specifications. See Specifications schema below. |
| desired_delivery_date | datetime | optional | Desired delivery date for this item (ISO 8601, e.g., "2026-05-15T00:00:00Z"). |
| desired_delivery_lead_time_days | integer | optional | Desired lead time in days for this line item. Overrides the header-level value. |
| detail | string | optional | Additional notes for this line. Max 1,000 chars. |
| raw_data | object | optional | Arbitrary JSON for this line item. |
Specifications Object
| Field | Type | Required | Description |
|---|---|---|---|
| manufacturer_code | string | optional | Manufacturer part number (e.g., "6ES7214-1AG40-0XB0"). Max 100 chars. |
| manufacturer_name | string | optional | Manufacturer name (e.g., "Siemens"). Max 200 chars. |
| manufacturer_description | string | optional | Manufacturer's description. Max 500 chars. |
| buyer_code | string | optional | Internal code in your system (e.g., "MAT-001234"). Max 100 chars. |
| buyer_code_description | string | optional | Description for the internal code. Max 500 chars. |
| buyer_code_system | string | optional | Source system name (e.g., "SAP", "Calipso"). Max 50 chars. |
| technical_specs | string | optional | Free-text technical specs (e.g., "220V, 50Hz, IP55"). Max 2,000 chars. |
| requirements | string | optional | Additional requirements (e.g., "ISO 9001 certification required"). Max 2,000 chars. |
Attachment Object
| Field | Type | Required | Description |
|---|---|---|---|
| url | string | required | Publicly accessible URL to download the file. Max 2,000 chars. |
| filename | string | required | Original filename (e.g., "plano_motor.pdf"). Max 255 chars. |
| description | string | optional | Description of the attachment. Max 500 chars. |
| file_type | string | optional | MIME type (auto-detected if not provided). Max 100 chars. |
Deduplication Logic
Each requisition is identified by its (scoped to your organization):
- New: If no existing requisition is found, a new one is created with status .
- Update: If an existing requisition with status is found, it is updated in-place (items are fully replaced).
- Supersede: If an existing requisition with status is found, it is reactivated (back to PENDING) with the new payload.
- Launched: If the requisition was already launched as a Purchase Request (), the import is rejected. The active PR cannot be overwritten.
- Discarded: If the requisition was previously discarded (), it is reactivated (back to PENDING) with the new payload. Useful when the ERP cancels and later re-sends it.
curl -X POST https://api.gosourced.ai/api/v1/requisitions \
-H "X-API-Key: sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"requisitions": [
{
"external_id": "REQ-2026-0042",
"items": [
{
"description": "Bearing SKF 6205",
"quantity": 10
}
]
}
]
}'Response
ERPImportResult
| Field | Type | Required | Description |
|---|---|---|---|
| success | boolean | required | true if error_count is 0. |
| created_count | integer | required | Number of new requisitions created. |
| updated_count | integer | required | Number of existing PENDING requisitions updated. |
| skipped_count | integer | required | Number of skipped requisitions (currently always 0). |
| error_count | integer | required | Number of requisitions that failed to import. |
| errors | array | required | Array of {index, external_id, error} for each failed requisition. |
| requisition_ids | array | required | Internal Sourced IDs of created/updated requisitions. |
{
"success": true,
"created_count": 1,
"updated_count": 0,
"skipped_count": 0,
"error_count": 0,
"errors": [],
"requisition_ids": [1234]
}List Requisitions
/api/v1/requisitionsAPI Key RequiredRetrieve a paginated list of your imported requisitions. Returns only requisitions created via the API.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| page | integer | optional | Page number (default: 1). |
| page_size | integer | optional | Items per page, 1-100 (default: 20). |
| status | string | optional | Filter by status: "PENDING", "LAUNCHED", "DISCARDED", "SUPERSEDED". |
curl -H "X-API-Key: sk_live_abc123..." \
"https://api.gosourced.ai/api/v1/requisitions?page=1&page_size=20&status=PENDING"{
"data": [
{
"id": 1234,
"external_id": "REQ-2026-0042",
"status": "PENDING",
"requester_name": "Juan Pérez",
"description": "Repuestos línea producción",
"items": [...],
"imported_at": "2026-03-07T14:30:00Z"
}
],
"total": 45,
"page": 1,
"page_size": 20,
"has_more": true
}Get Requisition Detail
/api/v1/requisitions/{requisition_id}API Key RequiredRetrieve a single requisition by its internal Sourced ID, including all items.
curl -H "X-API-Key: sk_live_abc123..." \
https://api.gosourced.ai/api/v1/requisitions/1234Returns the full requisition object. Returns if not found or not owned by your organization.
Check Existing Requisitions
/api/v1/requisitions/check-existingAPI Key RequiredCheck which external_ids already exist in Sourced before importing. Useful to avoid unnecessary API calls.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| external_ids | array | required | List of external_id strings to check (1-100 items). |
curl -X POST https://api.gosourced.ai/api/v1/requisitions/check-existing \
-H "X-API-Key: sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"external_ids": ["REQ-2026-0042", "REQ-2026-0043", "REQ-2026-0044"]
}'{
"existing": ["REQ-2026-0042"],
"not_found": ["REQ-2026-0043", "REQ-2026-0044"]
}Cancel Requisition
/api/v1/requisitions/cancelAPI Key RequiredCancel a PENDING requisition by sending the external_id in the request body.
Only requisitions with status can be cancelled. If the requisition was already launched as a Purchase Request, it must be cancelled within Sourced.
| Field | Type | Required | Description |
|---|---|---|---|
| external_id | string | required | The requisition ID in your external system (the same one used when importing) |
| reason | string | optional | Cancellation reason (stored for audit purposes) |
curl -X POST https://api.gosourced.ai/api/v1/requisitions/cancel \
-H "X-API-Key: sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"external_id": "REQ-2026-0042",
"reason": "Cancelado desde ERP"
}'{
"status": "discarded",
"external_id": "REQ-2026-0042"
}Possible responses:
discarded— Requisition was successfully discarded.already_discarded— Requisition was already discarded (idempotent).already_superseded— Requisition was already superseded by a newer version.- Requisition was already launched — returns with details.
- Requisition not found — returns .
List Purchase Orders
/api/v1/purchase-ordersAPI Key RequiredRetrieve purchase orders for your organization. Supports incremental sync via the 'since' parameter.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| page | integer | optional | Page number (default: 1). |
| page_size | integer | optional | Items per page, 1-100 (default: 20). |
| status | string | optional | Filter by status: "DRAFT", "CREATED", "SENT", "CONFIRMED", "REJECTED", "CANCELLED". |
| since | datetime | optional | ISO 8601 timestamp. Returns only POs created or updated after this date. |
| requisition_external_id | string | optional | Filter by the original requisition's external_id from your ERP. Returns POs generated from that requisition. |
curl -H "X-API-Key: sk_live_abc123..." \
"https://api.gosourced.ai/api/v1/purchase-orders?since=2026-03-01T00:00:00Z&status=CONFIRMED"{
"data": [
{
"id": 567,
"code": "PO-2026-0089",
"status": "CONFIRMED",
"award_type": "FULL",
"supplier_name": "Distribuidora Industrial SA",
"supplier_id": 42,
"supplier_external_id": "PROV-CAL-00123",
"supplier_tax_id": "30712345678",
"supplier_email": "ventas@distribuidora.com",
"total_price": 285000.00,
"currency": "ARS",
"delivery_address": "Av. Corrientes 1234, CABA",
"delivery_address_code": "001",
"observations": "Entregar en horario de mañana. Coordinar con depósito.",
"delivery_lead_time_days": 15,
"expected_delivery_date": "2026-03-20T16:00:00Z",
"payment_terms_code": "NET30",
"awarded_at": "2026-03-05T16:00:00Z",
"awarded_by_name": "Juan Pérez",
"awarded_by_email": "juan.perez@empresa.com",
"created_at": "2026-03-05T16:00:00Z",
"updated_at": "2026-03-06T10:30:00Z",
"purchase_request_id": 1234,
"requisition_external_id": "REQ-2026-00142",
"exchange_rate_data": {
"date": "2026-03-05",
"usdToArs": 1450.0,
"arsToUsd": 0.00069
},
"total_nominal_savings": 15000.00,
"total_real_savings": 8500.00,
"savings_currency": "ARS",
"items": [
{
"description": "Bearing SKF 6205",
"quantity": 10,
"unit_price": 28500.00,
"total_price": 285000.00,
"unit_of_measure": "UN",
"currency": "ARS",
"delivery_lead_time_days": 15,
"expected_delivery_date": "2026-03-20T16:00:00Z",
"external_line_id": "REQ-2026-0042-L10",
"manufacturer_code": "6205-2RS"
}
]
}
],
"total": 12,
"page": 1,
"page_size": 20,
"has_more": false
}Get Purchase Order Detail
/api/v1/purchase-orders/{po_id}API Key RequiredRetrieve a single purchase order by its internal Sourced ID, including all line items with traceability back to your ERP via external_line_id.
curl -H "X-API-Key: sk_live_abc123..." \
https://api.gosourced.ai/api/v1/purchase-orders/567This endpoint requires the internal Sourced ID (). If you need to find purchase orders using your ERP's requisition ID, use the endpoint with the query parameter instead:
You can also combine it with other filters: to filter by PO status, for incremental sync, and / for pagination.
Purchase Order Object
| Field | Type | Required | Description |
|---|---|---|---|
| id | integer | required | Sourced internal PO ID. |
| code | string | required | Human-readable PO code. |
| status | string | required | PO status: "DRAFT", "CREATED", "SENT", "CONFIRMED", "REJECTED", "CANCELLED". |
| award_type | string | optional | Award type: FULL (single supplier) or PARTIAL (split award across multiple suppliers). |
| supplier_name | string | required | Supplier name. |
| supplier_id | integer | optional | Sourced internal supplier ID. |
| total_price | float | optional | Total PO value. |
| currency | string | optional | Currency code. |
| delivery_address | string | optional | Delivery address. |
| delivery_address_code | string | optional | Code of the linked organization delivery address (e.g. "001"). Use it to map the destination back to your ERP. Null for free-text addresses with no linked record. |
| observations | string | optional | Free-text comments / observations entered by the buyer in the pre-award review step. Falls back to special conditions quoted by the supplier when the buyer left no note. Null when neither is present. |
| delivery_lead_time_days | integer | optional | Header-level delivery lead time in days, as quoted by the supplier. When the supplier quotes different lead times per line, items can have different values — see items[].delivery_lead_time_days for the per-line value. |
| expected_delivery_date | datetime | optional | Computed delivery date (awarded_at + delivery_lead_time_days). Null if either input is missing. Use items[].expected_delivery_date for per-line dates. |
| payment_terms_code | string | optional | Payment terms code. |
| awarded_at | datetime | optional | When the PO was awarded (ISO 8601). |
| awarded_by_name | string | optional | Name of the user who awarded this PO. |
| awarded_by_email | string | optional | Email of the user who awarded this PO. |
| created_at | datetime | optional | Creation timestamp (ISO 8601). |
| updated_at | datetime | optional | Last update timestamp (ISO 8601). |
| purchase_request_id | integer | optional | ID of the originating purchase request. |
| requisition_external_id | string | optional | Source-system document ID from your ERP (e.g. requisition number in Calipso/SAP/JDE). Resolved from the originating ERPRequisition when available; otherwise falls back to the PR's external_id. May be a comma-separated list when a single PR aggregates multiple source requisitions. |
| exchange_rate_data | object | optional | Exchange rates at award time. Format: {"date": "2026-03-05", "usdToArs": 1450.0, "arsToUsd": 0.00069}. Null if no data available. |
| total_nominal_savings | float | optional | Total nominal savings vs historical prices (no inflation adjustment). |
| total_real_savings | float | optional | Total real savings vs historical prices (inflation adjusted). |
| savings_currency | string | optional | Currency of the savings amounts. |
| items | array | required | PO line items. See PO Item schema below. |
PO Item Object
| Field | Type | Required | Description |
|---|---|---|---|
| description | string | required | Item description. |
| quantity | float | optional | Quantity ordered. |
| unit_price | float | optional | Price per unit. |
| total_price | float | optional | Total line price (quantity x unit_price). |
| unit_of_measure | string | optional | Unit of measure. |
| currency | string | optional | Currency code. |
| delivery_lead_time_days | integer | optional | Delivery lead time in days for this line, as quoted by the supplier. Different items in the same PO can have different lead times. |
| expected_delivery_date | datetime | optional | Computed delivery date for this line (PO.awarded_at + the line's delivery_lead_time_days). Null if either input is missing. |
| external_line_id | string | optional | Original line ID from your ERP — use this to match PO items back to your requisition lines. |
| manufacturer_code | string | optional | Manufacturer part number. |
- Lead time exists at two levels: at the header (the supplier's headline lead time) and per line item (the precise per-item value). When the supplier quotes different lead times per line, prefer the per-line value.
- is a computed field: . Sourced computes it; the supplier does not send a date directly.
- If is null, will be null too. This typically means the supplier did not include a lead time in their quote.
Update Purchase Order Status
/api/v1/purchase-orders/{po_id}/statusAPI Key RequiredUpdate a purchase order's status to reflect its progress in your external system (ERP).
Allowed status transitions:
| From | To | Meaning |
|---|---|---|
| DRAFT | CREATED | The PO was created in your ERP. |
| CREATED | CONFIRMED | The PO was fully approved in your ERP. |
| DRAFT | CONFIRMED | Shortcut when no intermediate step is needed. |
| DRAFT | REJECTED | PO was rejected in your ERP. The PR is reopened in Sourced. |
| CREATED | REJECTED | PO was rejected in your ERP after being created. The PR is reopened in Sourced. |
| DRAFT / CREATED / SENT / CONFIRMED | CANCELLED | The purchase is not happening. The PO is cancelled and so is the PR — nothing reopens. Use REJECTED instead if the need still exists and you want to re-award. |
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | required | Target status: CREATED (PO created in your ERP), CONFIRMED (PO fully approved in your ERP), REJECTED (PO rejected, reopens the PR) or CANCELLED (purchase dropped, cancels both the PO and the PR). |
| external_id | string | optional | PO number or code in your ERP (e.g., OC-CAL-00045678). Stored for traceability. |
| notes | string | optional | Optional notes about the status change. |
curl -X POST https://api.gosourced.ai/api/v1/purchase-orders/567/status \
-H "X-API-Key: sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"status": "CREATED",
"external_id": "OC-CAL-00045678",
"notes": "Creada en Calipso"
}'{
"status": "created",
"po_id": 567,
"code": "PO-A1B2C3D4"
}List Suppliers
/api/v1/suppliersAPI Key RequiredList suppliers for your organization. Use ?has_erp_code=false to find unmapped suppliers. Use ?detail=full for contacts, categories, and coverage.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| page | integer | optional | Page number (default: 1). |
| page_size | integer | optional | Results per page (1-200, default: 50). |
| search | string | optional | Search by name, custom name, email, tax ID, or ERP code. |
| erp_code | string | optional | Filter by exact ERP code. |
| has_erp_code | boolean | optional | true = only mapped to ERP, false = only unmapped. |
| detail | string | optional | Set to 'full' to include contacts, categories, and coverage. |
# Light (default)
curl -H "X-API-Key: sk_live_abc123..." \
"https://api.gosourced.ai/api/v1/suppliers?has_erp_code=false"
# Full detail
curl -H "X-API-Key: sk_live_abc123..." \
"https://api.gosourced.ai/api/v1/suppliers?search=30712345678&detail=full"// Light response
{
"data": [
{
"id": 42,
"name": "Distribuidora Industrial SA",
"email": "ventas@distribuidora.com",
"tax_id": "30712345678",
"country_code": "AR",
"city": "Buenos Aires",
"is_active": true,
"is_preferred": true,
"erp_code": "PROV-CAL-00123",
"erp_type": "SAP_B1"
}
],
"total": 85,
"page": 1,
"page_size": 50,
"has_more": true
}
// Full response (?detail=full)
{
"data": [
{
"id": 42,
"name": "Distribuidora Industrial SA",
"email": "ventas@distribuidora.com",
"tax_id": "30712345678",
"country_code": "AR",
"city": "Buenos Aires",
"is_active": true,
"is_preferred": true,
"erp_code": "PROV-CAL-00123",
"erp_type": "SAP_B1",
"address": "Av. Corrientes 1234",
"state_code": "CABA",
"website": "https://distribuidora.com",
"description": "Distribuidor de insumos industriales",
"tax_regime": null,
"employee_count": "50+",
"years_in_business": "5+",
"performance_score": 4.2,
"reliability_score": 4.5,
"quality_score": 4.0,
"contacts": [
{
"name": "Juan Pérez",
"email": "juan@distribuidora.com",
"phone": "+54 11 5555-1234",
"role": "SALES",
"is_primary": true
}
],
"categories": [
{ "id": 15, "code": "IND-001", "name": "Insumos Industriales", "level": "LEVEL_1" }
],
"coverage": [
{ "country": "Argentina", "province": null, "is_nationwide": true }
]
}
],
"total": 1,
"page": 1,
"page_size": 50,
"has_more": false
}Create Supplier
/api/v1/suppliersAPI Key RequiredCreate a supplier for your organization. At least one of tax_id or erp_code is required. At least one contact with role 'sales' is required. If a global supplier with the same tax ID already exists, it is reused and linked to your organization.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | Supplier name for your organization. |
| tax_id | string | optional | Tax ID (CUIT, CNPJ, RUT, etc.). At least one of tax_id or erp_code is required. |
| erp_code | string | optional | Supplier code in your ERP. At least one of tax_id or erp_code is required. |
| erp_type | string | optional | ERP type (SAP_B1, JDE, ORACLE_CLOUD, etc.). |
| country_code | string | optional | ISO 3166-1 country code (e.g., AR, BR, US). |
| city | string | optional | Supplier city. |
| address | string | optional | Full address. |
| state_code | string | optional | State/province (e.g., CABA, SP). |
| website | string | optional | Supplier website. |
| contacts | array | required | List of contacts. At least one with role 'sales' is required. |
| contacts[].name | string | required | Contact name. |
| contacts[].email | string | required | Contact email. |
| contacts[].phone | string | optional | Phone (optional). |
| contacts[].role | string | required | Role: SALES or LOGISTICS. |
| contacts[].is_primary | boolean | optional | true if primary contact (default: false). |
curl -X POST https://api.gosourced.ai/api/v1/suppliers \
-H "X-API-Key: sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"name": "Distribuidora Industrial SA",
"tax_id": "30712345678",
"erp_code": "PROV-CAL-00123",
"erp_type": "SAP_B1",
"country_code": "AR",
"city": "Buenos Aires",
"address": "Av. Corrientes 1234",
"contacts": [
{
"name": "Juan Pérez",
"email": "juan@distribuidora.com",
"phone": "+54 11 5555-1234",
"role": "SALES",
"is_primary": true
},
{
"name": "María García",
"email": "maria@distribuidora.com",
"role": "LOGISTICS"
}
]
}'// 201 Created
{
"id": 42,
"name": "Distribuidora Industrial SA",
"email": null,
"tax_id": "30712345678",
"country_code": "AR",
"city": "Buenos Aires",
"is_active": true,
"is_preferred": false,
"erp_code": "PROV-CAL-00123",
"erp_type": "SAP_B1",
"address": "Av. Corrientes 1234",
"state_code": null,
"website": null,
"description": null,
"tax_regime": null,
"employee_count": null,
"years_in_business": null,
"performance_score": null,
"reliability_score": null,
"quality_score": null,
"contacts": [
{
"name": "Juan Pérez",
"email": "juan@distribuidora.com",
"phone": "+54 11 5555-1234",
"role": "SALES",
"is_primary": true
},
{
"name": "María García",
"email": "maria@distribuidora.com",
"phone": null,
"role": "LOGISTICS",
"is_primary": false
}
],
"categories": [],
"coverage": []
}Schema Reference
Quick reference of all request/response schemas used across endpoints.
Requisition Statuses
| Status | Description |
|---|---|
| PENDING | Imported, awaiting review by a buyer in Sourced. |
| LAUNCHED | Buyer has launched the requisition as a Purchase Request. |
| DISCARDED | Requisition was manually discarded. |
| SUPERSEDED | A newer version was imported with the same external_id. |
Purchase Order Statuses
| Status | Description |
|---|---|
| DRAFT | PO created in Sourced, pending sync to external ERP. |
| CREATED | PO created in the external ERP, pending approval. |
| CONFIRMED | PO fully approved in the external ERP. |
| REJECTED | PO rejected in the external ERP. The associated PR is automatically reopened. |
| CANCELLED | Purchase dropped. The PO is cancelled and so is the associated PR — nothing reopens. |
Reference codes
Catalogs of currencies and payment terms accepted by the API. Use them to map these values to the equivalent codes in your ERP.
Currencies
Sourced does not use a closed currency enum: any valid 3-letter ISO 4217 code is accepted. The most commonly used currencies by our customers are:
| Code | Currency |
|---|---|
| ARS | Argentine peso |
| USD | US dollar |
| EUR | Euro |
| BRL | Brazilian real |
Payment terms (payment_terms_code)
Global catalog of payment conditions available in Sourced. Use the code (Code column) in the PO's payment_terms_code field. The type field describes the nature of the payment: IMMEDIATE (on receipt), ADVANCE (prepaid), NET_DAYS (X days from invoice).
| Code | Name | Type | Days | Description |
|---|---|---|---|---|
| COD | Cash On Delivery | IMMEDIATE | 0 | Cash on delivery |
| IMM | Immediate Payment | IMMEDIATE | 0 | Immediate / Cash payment |
| ADV100 | Advance Payment | ADVANCE | 0 | 100% advance payment |
| ADV50 | Advance 50% | ADVANCE | 0 | 50% advance payment |
| NET7 | Net 7 Days | NET_DAYS | 7 | Payment due 7 days after invoice date |
| NET10 | Net 10 Days | NET_DAYS | 10 | Payment due 10 days after invoice date |
| NET15 | Net 15 Days | NET_DAYS | 15 | Payment due 15 days after invoice date |
| NET20 | Net 20 Days | NET_DAYS | 20 | Payment due 20 days after invoice date |
| NET21 | Net 21 Days | NET_DAYS | 21 | Payment due 21 days after invoice date |
| NET30 | Net 30 Days | NET_DAYS | 30 | Payment due 30 days after invoice date |
| EOM30 | End of Month + 30 | NET_DAYS | 30 | Payment due end of month plus 30 days |
| NET35 | Net 35 Days | NET_DAYS | 35 | Payment due 35 days after invoice date |
| NET40 | Net 40 Days | NET_DAYS | 40 | Payment due 40 days after invoice date |
| NET45 | Net 45 Days | NET_DAYS | 45 | Payment due 45 days after invoice date |
| NET60 | Net 60 Days | NET_DAYS | 60 | Payment due 60 days after invoice date |
| NET75 | Net 75 Days | NET_DAYS | 75 | Payment due 75 days after invoice date |
| NET90 | Net 90 Days | NET_DAYS | 90 | Payment due 90 days after invoice date |
Units of Measure
Unit of measure codes accepted in requisition items. Sent in the unit_of_measure field.
| Code | Unit |
|---|---|
| EA | Each / Unit |
| PCS | Pieces |
| KG | Kilogram |
| G | Gram |
| LB | Pound |
| OZ | Ounce |
| M | Meter |
| CM | Centimeter |
| MM | Millimeter |
| IN | Inch |
| FT | Foot |
| YD | Yard |
| L | Liter |
| ML | Milliliter |
| GAL | Gallon |
| QT | Quart |
| PT | Pint |
| FL_OZ | Fluid ounce |
| M2 | Square meter |
| CM2 | Square centimeter |
| FT2 | Square foot |
| IN2 | Square inch |
| YD2 | Square yard |
| M3 | Cubic meter |
| CM3 | Cubic centimeter |
| FT3 | Cubic foot |
| IN3 | Cubic inch |
| YD3 | Cubic yard |
| BOX | Box |
| CASE | Case |
| PACK | Pack |
| SET | Set |
| KIT | Kit |
| BUNDLE | Bundle |
| ROLL | Roll |
| SHEET | Sheet |
| PALLET | Pallet |
| DRUM | Drum |
| BAG | Bag |
| BOTTLE | Bottle |
| CEN | Hundred |
Integration Flow
Typical integration pattern for a scheduled ERP sync (e.g., cron job every 15 minutes):
Collect new requisitions from ERP
Query your ERP for approved requisitions that haven't been synced to Sourced yet.
Check existing (optional)
Call POST /requisitions/check-existing with external_ids to filter out already-synced requisitions.
Import requisitions
Call POST /requisitions with the batch of new/updated requisitions. Store the returned requisition_ids.
Poll new purchase orders
Call GET /purchase-orders?since={last_sync_timestamp}&status=DRAFT to fetch new POs. Create the PO in your ERP and call POST /purchase-orders/{id}/status with {"status": "CREATED"}.
Confirm approved POs
When the PO is approved in your ERP, call POST /purchase-orders/{id}/status with {"status": "CONFIRMED"} to close the loop.
# Step 1: Get pending requisitions from ERP
ERP_REQS=$(query_erp_pending_requisitions)
# Step 2: Check which ones already exist in Sourced
EXISTING=$(curl -s -X POST \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{"external_ids": $ERP_REQ_IDS}" \
https://api.gosourced.ai/api/v1/requisitions/check-existing)
# Step 3: Import only new requisitions
NEW_REQS=$(filter_not_found $ERP_REQS $EXISTING)
curl -s -X POST \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{"requisitions": $NEW_REQS}" \
https://api.gosourced.ai/api/v1/requisitions
# Step 4: Pull new POs since last sync
POS=$(curl -s \
-H "X-API-Key: $API_KEY" \
"https://api.gosourced.ai/api/v1/purchase-orders?since=$LAST_SYNC&status=DRAFT")
# Step 5: Create POs in ERP and update status
for PO in $POS; do
create_po_in_erp $PO
curl -s -X POST \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{"status": "CREATED", "external_id": "$ERP_PO_NUMBER"}" \
"https://api.gosourced.ai/api/v1/purchase-orders/$PO_ID/status"
done
# Step 6: When PO is approved in ERP, confirm it
curl -s -X POST \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "CONFIRMED"}' \
"https://api.gosourced.ai/api/v1/purchase-orders/$PO_ID/status"Full Example
A realistic import request with all available fields populated:
curl -X POST https://api.gosourced.ai/api/v1/requisitions \
-H "X-API-Key: sk_live_abc123..." \
-H "Content-Type: application/json" \
-d '{
"requisitions": [
{
"external_id": "CAL-REQ-2026-0042",
"description": "Repuestos bomba centrífuga Planta Norte",
"requester_name": "Carlos Rodríguez",
"requester_email": "carlos.rodriguez@empresa.com",
"comments": "Urgente: bomba fuera de servicio desde 03/03. <b>Necesitamos entrega express.</b>",
"delivery_address": "Av. Industrial 4500, Parque Industrial Pilar, Buenos Aires",
"delivery_address_code": "PLANTA-NORTE",
"desired_delivery_lead_time_days": 7,
"offer_deadline": "2026-03-10T18:00:00Z",
"total_estimated_value": 1250000.00,
"currency": "ARS",
"department_code": "MANT-001",
"priority_level": "HIGH",
"items": [
{
"external_line_id": "CAL-REQ-2026-0042-L10",
"description": "Sello mecánico para bomba centrífuga KSB ETA 50-200",
"quantity": 2,
"unit_of_measure": "UN",
"target_price": 185000.00,
"estimated_price": 370000.00,
"currency": "ARS",
"category": "Repuestos Bombas",
"material_code": "MAT-BOM-0234",
"desired_delivery_lead_time_days": 10,
"detail": "Sello tipo cartucho, material: carburo de silicio / carburo de silicio",
"specifications": {
"manufacturer_code": "KSB-SEAL-50200",
"manufacturer_name": "KSB",
"manufacturer_description": "Mechanical seal for ETA 50-200 centrifugal pump",
"buyer_code": "MAT-BOM-0234",
"buyer_code_description": "Sello mecánico bomba KSB ETA 50-200",
"buyer_code_system": "Calipso",
"technical_specs": "Diámetro eje: 35mm, Material caras: SiC/SiC, Elastómeros: Viton",
"requirements": "Debe incluir certificado de calidad. Preferencia por repuesto original KSB."
}
},
{
"external_line_id": "CAL-REQ-2026-0042-L20",
"description": "Rodamiento SKF 6310-2RS",
"quantity": 4,
"unit_of_measure": "UN",
"target_price": 45000.00,
"currency": "ARS",
"category": "Rodamientos",
"material_code": "MAT-ROD-0089",
"specifications": {
"manufacturer_code": "6310-2RS1",
"manufacturer_name": "SKF",
"technical_specs": "50x110x27mm, sellado ambos lados, grasa estándar"
}
},
{
"external_line_id": "CAL-REQ-2026-0042-L30",
"description": "Aceite lubricante ISO VG 68",
"quantity": 20,
"unit_of_measure": "LT",
"target_price": 5500.00,
"currency": "ARS",
"category": "Lubricantes",
"specifications": {
"technical_specs": "Aceite mineral ISO VG 68, índice de viscosidad > 95"
}
}
],
"attachments": [
{
"url": "https://erp.empresa.com/files/plano-bomba-eta-50-200.pdf",
"filename": "plano_bomba_KSB_ETA_50-200.pdf",
"description": "Plano de despiece bomba KSB ETA 50-200",
"file_type": "application/pdf"
}
],
"raw_data": {
"calipso_doc_type": "SOL",
"calipso_doc_number": "0042",
"calipso_branch": "001",
"approved_by": "María González",
"cost_center": "CC-MANT-NORTE"
}
}
]
}'{
"success": true,
"created_count": 1,
"updated_count": 0,
"skipped_count": 0,
"error_count": 0,
"errors": [],
"requisition_ids": [1234]
}