API Documentation

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.

Example: Authenticated request
curl -H "X-API-Key: sk_live_abc123..." \
  https://api.gosourced.ai/api/v1/requisitions
Security: Treat your API key like a password. Do not expose it in client-side code, public repositories, or logs. If compromised, revoke it immediately from the admin panel and create a new one.

Base URL

EnvironmentBase URL
Productionhttps://api.gosourced.ai
Developmenthttps://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.

Error response format
{
  "detail": "Invalid or revoked API key."
}
StatusMeaning
200Success
400Bad Request — validation error or malformed body
401Unauthorized — missing or invalid API key
404Not Found — resource does not exist or is not accessible
422Unprocessable Entity — request body failed schema validation
429Too Many Requests — rate limit exceeded
500Internal Server Error — unexpected error on our side

Error Examples

401 — Invalid API key
{
  "detail": "Invalid or revoked API key."
}
422 — Validation error (e.g., missing required field)
{
  "detail": [
    {
      "loc": ["body", "requisitions", 0, "items", 0, "quantity"],
      "msg": "Input should be greater than 0",
      "type": "greater_than"
    }
  ]
}
200 — Partial success (some requisitions failed)
{
  "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

GET/api/v1/health

Verify the API is reachable. No authentication required.

Request
curl https://api.gosourced.ai/api/v1/health
Response — 200 OK
{
  "status": "ok",
  "api": "v1"
}

Import Requisitions

POST/api/v1/requisitionsAPI Key Required

Import 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

FieldTypeRequiredDescription
external_idstringrequiredUnique ID in your ERP (deduplication key). Max 250 chars.
itemsarrayrequiredLine items (1-200 items). See Item schema below.
requester_namestringoptionalName of the person requesting. Max 200 chars.
requester_emailstringoptionalEmail of the requester. Max 200 chars.
descriptionstringoptionalRequisition title or summary. Max 500 chars.
commentsstringoptionalAdditional instructions for buyers (HTML supported). Max 15,000 chars.
delivery_addressstringoptionalFree-text delivery address. Max 500 chars.
delivery_address_codestringoptionalCode matching an address configured in Sourced. Max 50 chars.
desired_delivery_lead_time_daysintegeroptionalDesired lead time in days from PO confirmation. Applied as default to all items.
offer_deadlinedatetimeoptionalDeadline for supplier quotations (ISO 8601).
total_estimated_valuefloatoptionalTotal estimated value. Auto-calculated from items if omitted.
currencystringoptionalCurrency code (e.g., "ARS", "USD"). Defaults to "ARS". Max 10 chars.
department_codestringoptionalDepartment/cost center code (matched against Sourced departments). Max 50 chars.
priority_levelstringoptionalPriority: "LOW", "MEDIUM", "HIGH", or "CRITICAL".
attachmentsarrayoptionalFile attachments (max 20). See Attachment schema below.
raw_dataobjectoptionalArbitrary JSON from your ERP, stored for traceability.

Item Object

FieldTypeRequiredDescription
descriptionstringrequiredItem name or description. Max 1,000 chars.
quantityfloatrequiredRequired quantity (must be > 0).
external_line_idstringoptionalLine ID in your ERP (e.g., "REQ-001-L10"). Returned in POs for traceability. Max 100 chars.
unit_of_measurestringoptionalUOM code (e.g., "KG", "EA", "LT", "M", "UN"). Matched against your org catalog. Max 50 chars.
target_pricefloatoptionalTarget/budget price per unit.
estimated_pricefloatoptionalEstimated total price for this line.
currencystringoptionalCurrency for prices (e.g., "ARS", "USD"). Max 10 chars.
categorystringoptionalCategory from your ERP. Max 200 chars.
material_codestringoptionalMaterial/part code in your ERP (e.g., SAP material code). Max 100 chars.
specificationsobjectoptionalTechnical specifications. See Specifications schema below.
desired_delivery_datedatetimeoptionalDesired delivery date for this item (ISO 8601, e.g., "2026-05-15T00:00:00Z").
desired_delivery_lead_time_daysintegeroptionalDesired lead time in days for this line item. Overrides the header-level value.
detailstringoptionalAdditional notes for this line. Max 1,000 chars.
raw_dataobjectoptionalArbitrary JSON for this line item.

Specifications Object

FieldTypeRequiredDescription
manufacturer_codestringoptionalManufacturer part number (e.g., "6ES7214-1AG40-0XB0"). Max 100 chars.
manufacturer_namestringoptionalManufacturer name (e.g., "Siemens"). Max 200 chars.
manufacturer_descriptionstringoptionalManufacturer's description. Max 500 chars.
buyer_codestringoptionalInternal code in your system (e.g., "MAT-001234"). Max 100 chars.
buyer_code_descriptionstringoptionalDescription for the internal code. Max 500 chars.
buyer_code_systemstringoptionalSource system name (e.g., "SAP", "Calipso"). Max 50 chars.
technical_specsstringoptionalFree-text technical specs (e.g., "220V, 50Hz, IP55"). Max 2,000 chars.
requirementsstringoptionalAdditional requirements (e.g., "ISO 9001 certification required"). Max 2,000 chars.

Attachment Object

FieldTypeRequiredDescription
urlstringrequiredPublicly accessible URL to download the file. Max 2,000 chars.
filenamestringrequiredOriginal filename (e.g., "plano_motor.pdf"). Max 255 chars.
descriptionstringoptionalDescription of the attachment. Max 500 chars.
file_typestringoptionalMIME 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.
Request — Minimal example
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

FieldTypeRequiredDescription
successbooleanrequiredtrue if error_count is 0.
created_countintegerrequiredNumber of new requisitions created.
updated_countintegerrequiredNumber of existing PENDING requisitions updated.
skipped_countintegerrequiredNumber of skipped requisitions (currently always 0).
error_countintegerrequiredNumber of requisitions that failed to import.
errorsarrayrequiredArray of {index, external_id, error} for each failed requisition.
requisition_idsarrayrequiredInternal Sourced IDs of created/updated requisitions.
Response — 200 OK
{
  "success": true,
  "created_count": 1,
  "updated_count": 0,
  "skipped_count": 0,
  "error_count": 0,
  "errors": [],
  "requisition_ids": [1234]
}

List Requisitions

GET/api/v1/requisitionsAPI Key Required

Retrieve a paginated list of your imported requisitions. Returns only requisitions created via the API.

Query Parameters

FieldTypeRequiredDescription
pageintegeroptionalPage number (default: 1).
page_sizeintegeroptionalItems per page, 1-100 (default: 20).
statusstringoptionalFilter by status: "PENDING", "LAUNCHED", "DISCARDED", "SUPERSEDED".
Request
curl -H "X-API-Key: sk_live_abc123..." \
  "https://api.gosourced.ai/api/v1/requisitions?page=1&page_size=20&status=PENDING"
Response — 200 OK
{
  "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

GET/api/v1/requisitions/{requisition_id}API Key Required

Retrieve a single requisition by its internal Sourced ID, including all items.

Request
curl -H "X-API-Key: sk_live_abc123..." \
  https://api.gosourced.ai/api/v1/requisitions/1234

Returns the full requisition object. Returns if not found or not owned by your organization.

Check Existing Requisitions

POST/api/v1/requisitions/check-existingAPI Key Required

Check which external_ids already exist in Sourced before importing. Useful to avoid unnecessary API calls.

Request Body

FieldTypeRequiredDescription
external_idsarrayrequiredList of external_id strings to check (1-100 items).
Request
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"]
  }'
Response — 200 OK
{
  "existing": ["REQ-2026-0042"],
  "not_found": ["REQ-2026-0043", "REQ-2026-0044"]
}

Cancel Requisition

POST/api/v1/requisitions/cancelAPI Key Required

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

FieldTypeRequiredDescription
external_idstringrequiredThe requisition ID in your external system (the same one used when importing)
reasonstringoptionalCancellation reason (stored for audit purposes)
Request
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"
  }'
Response — 200 OK
{
  "status": "discarded",
  "external_id": "REQ-2026-0042"
}

Possible responses:

  • discardedRequisition was successfully discarded.
  • already_discardedRequisition was already discarded (idempotent).
  • already_supersededRequisition was already superseded by a newer version.
  • Requisition was already launched — returns with details.
  • Requisition not found — returns .

List Purchase Orders

GET/api/v1/purchase-ordersAPI Key Required

Retrieve purchase orders for your organization. Supports incremental sync via the 'since' parameter.

Query Parameters

FieldTypeRequiredDescription
pageintegeroptionalPage number (default: 1).
page_sizeintegeroptionalItems per page, 1-100 (default: 20).
statusstringoptionalFilter by status: "DRAFT", "CREATED", "SENT", "CONFIRMED", "REJECTED", "CANCELLED".
sincedatetimeoptionalISO 8601 timestamp. Returns only POs created or updated after this date.
requisition_external_idstringoptionalFilter by the original requisition's external_id from your ERP. Returns POs generated from that requisition.
Request — Incremental sync
curl -H "X-API-Key: sk_live_abc123..." \
  "https://api.gosourced.ai/api/v1/purchase-orders?since=2026-03-01T00:00:00Z&status=CONFIRMED"
Response — 200 OK
{
  "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

GET/api/v1/purchase-orders/{po_id}API Key Required

Retrieve a single purchase order by its internal Sourced ID, including all line items with traceability back to your ERP via external_line_id.

Request
curl -H "X-API-Key: sk_live_abc123..." \
  https://api.gosourced.ai/api/v1/purchase-orders/567
Looking up POs by your requisition ID?

This 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:

GET /api/v1/purchase-orders?requisition_external_id=YOUR-REQ-ID

You can also combine it with other filters: to filter by PO status, for incremental sync, and / for pagination.

Purchase Order Object

FieldTypeRequiredDescription
idintegerrequiredSourced internal PO ID.
codestringrequiredHuman-readable PO code.
statusstringrequiredPO status: "DRAFT", "CREATED", "SENT", "CONFIRMED", "REJECTED", "CANCELLED".
award_typestringoptionalAward type: FULL (single supplier) or PARTIAL (split award across multiple suppliers).
supplier_namestringrequiredSupplier name.
supplier_idintegeroptionalSourced internal supplier ID.
total_pricefloatoptionalTotal PO value.
currencystringoptionalCurrency code.
delivery_addressstringoptionalDelivery address.
delivery_address_codestringoptionalCode 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.
observationsstringoptionalFree-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_daysintegeroptionalHeader-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_datedatetimeoptionalComputed 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_codestringoptionalPayment terms code.
awarded_atdatetimeoptionalWhen the PO was awarded (ISO 8601).
awarded_by_namestringoptionalName of the user who awarded this PO.
awarded_by_emailstringoptionalEmail of the user who awarded this PO.
created_atdatetimeoptionalCreation timestamp (ISO 8601).
updated_atdatetimeoptionalLast update timestamp (ISO 8601).
purchase_request_idintegeroptionalID of the originating purchase request.
requisition_external_idstringoptionalSource-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_dataobjectoptionalExchange rates at award time. Format: {"date": "2026-03-05", "usdToArs": 1450.0, "arsToUsd": 0.00069}. Null if no data available.
total_nominal_savingsfloatoptionalTotal nominal savings vs historical prices (no inflation adjustment).
total_real_savingsfloatoptionalTotal real savings vs historical prices (inflation adjusted).
savings_currencystringoptionalCurrency of the savings amounts.
itemsarrayrequiredPO line items. See PO Item schema below.

PO Item Object

FieldTypeRequiredDescription
descriptionstringrequiredItem description.
quantityfloatoptionalQuantity ordered.
unit_pricefloatoptionalPrice per unit.
total_pricefloatoptionalTotal line price (quantity x unit_price).
unit_of_measurestringoptionalUnit of measure.
currencystringoptionalCurrency code.
delivery_lead_time_daysintegeroptionalDelivery 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_datedatetimeoptionalComputed delivery date for this line (PO.awarded_at + the line's delivery_lead_time_days). Null if either input is missing.
external_line_idstringoptionalOriginal line ID from your ERP — use this to match PO items back to your requisition lines.
manufacturer_codestringoptionalManufacturer part number.
About delivery dates and lead times
  • 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

POST/api/v1/purchase-orders/{po_id}/statusAPI Key Required

Update a purchase order's status to reflect its progress in your external system (ERP).

Allowed status transitions:

FromToMeaning
DRAFTCREATEDThe PO was created in your ERP.
CREATEDCONFIRMEDThe PO was fully approved in your ERP.
DRAFTCONFIRMEDShortcut when no intermediate step is needed.
DRAFTREJECTEDPO was rejected in your ERP. The PR is reopened in Sourced.
CREATEDREJECTEDPO was rejected in your ERP after being created. The PR is reopened in Sourced.
DRAFT / CREATED / SENT / CONFIRMEDCANCELLEDThe 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.
FieldTypeRequiredDescription
statusstringrequiredTarget 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_idstringoptionalPO number or code in your ERP (e.g., OC-CAL-00045678). Stored for traceability.
notesstringoptionalOptional notes about the status change.
Request
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"
  }'
Response — 200 OK
{
  "status": "created",
  "po_id": 567,
  "code": "PO-A1B2C3D4"
}

List Suppliers

GET/api/v1/suppliersAPI Key Required

List suppliers for your organization. Use ?has_erp_code=false to find unmapped suppliers. Use ?detail=full for contacts, categories, and coverage.

Query Parameters

FieldTypeRequiredDescription
pageintegeroptionalPage number (default: 1).
page_sizeintegeroptionalResults per page (1-200, default: 50).
searchstringoptionalSearch by name, custom name, email, tax ID, or ERP code.
erp_codestringoptionalFilter by exact ERP code.
has_erp_codebooleanoptionaltrue = only mapped to ERP, false = only unmapped.
detailstringoptionalSet to 'full' to include contacts, categories, and coverage.
Request
# 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"
Response — 200 OK
// 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

POST/api/v1/suppliersAPI Key Required

Create 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

FieldTypeRequiredDescription
namestringrequiredSupplier name for your organization.
tax_idstringoptionalTax ID (CUIT, CNPJ, RUT, etc.). At least one of tax_id or erp_code is required.
erp_codestringoptionalSupplier code in your ERP. At least one of tax_id or erp_code is required.
erp_typestringoptionalERP type (SAP_B1, JDE, ORACLE_CLOUD, etc.).
country_codestringoptionalISO 3166-1 country code (e.g., AR, BR, US).
citystringoptionalSupplier city.
addressstringoptionalFull address.
state_codestringoptionalState/province (e.g., CABA, SP).
websitestringoptionalSupplier website.
contactsarrayrequiredList of contacts. At least one with role 'sales' is required.
contacts[].namestringrequiredContact name.
contacts[].emailstringrequiredContact email.
contacts[].phonestringoptionalPhone (optional).
contacts[].rolestringrequiredRole: SALES or LOGISTICS.
contacts[].is_primarybooleanoptionaltrue if primary contact (default: false).
Request
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"
      }
    ]
  }'
Response — 200 OK
// 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

StatusDescription
PENDINGImported, awaiting review by a buyer in Sourced.
LAUNCHEDBuyer has launched the requisition as a Purchase Request.
DISCARDEDRequisition was manually discarded.
SUPERSEDEDA newer version was imported with the same external_id.

Purchase Order Statuses

StatusDescription
DRAFTPO created in Sourced, pending sync to external ERP.
CREATEDPO created in the external ERP, pending approval.
CONFIRMEDPO fully approved in the external ERP.
REJECTEDPO rejected in the external ERP. The associated PR is automatically reopened.
CANCELLEDPurchase dropped. The PO is cancelled and so is the associated PR — nothing reopens.
Additional statuses such as RECEIVED (goods received), INVOICED (invoiced), and others will be added soon to reflect the full purchase order lifecycle.

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:

CodeCurrency
ARSArgentine peso
USDUS dollar
EUREuro
BRLBrazilian real
Pass the ISO 4217 code directly in the currency field (e.g. "currency": "EUR"). Sourced stores it as-is and returns it unchanged in API responses.

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

CodeNameTypeDaysDescription
CODCash On DeliveryIMMEDIATE0Cash on delivery
IMMImmediate PaymentIMMEDIATE0Immediate / Cash payment
ADV100Advance PaymentADVANCE0100% advance payment
ADV50Advance 50%ADVANCE050% advance payment
NET7Net 7 DaysNET_DAYS7Payment due 7 days after invoice date
NET10Net 10 DaysNET_DAYS10Payment due 10 days after invoice date
NET15Net 15 DaysNET_DAYS15Payment due 15 days after invoice date
NET20Net 20 DaysNET_DAYS20Payment due 20 days after invoice date
NET21Net 21 DaysNET_DAYS21Payment due 21 days after invoice date
NET30Net 30 DaysNET_DAYS30Payment due 30 days after invoice date
EOM30End of Month + 30NET_DAYS30Payment due end of month plus 30 days
NET35Net 35 DaysNET_DAYS35Payment due 35 days after invoice date
NET40Net 40 DaysNET_DAYS40Payment due 40 days after invoice date
NET45Net 45 DaysNET_DAYS45Payment due 45 days after invoice date
NET60Net 60 DaysNET_DAYS60Payment due 60 days after invoice date
NET75Net 75 DaysNET_DAYS75Payment due 75 days after invoice date
NET90Net 90 DaysNET_DAYS90Payment due 90 days after invoice date
The catalog is global to the entire platform and rarely changes. If you need an additional code for your integration, contact us.

Units of Measure

Unit of measure codes accepted in requisition items. Sent in the unit_of_measure field.

CodeUnit
EAEach / Unit
PCSPieces
KGKilogram
GGram
LBPound
OZOunce
MMeter
CMCentimeter
MMMillimeter
INInch
FTFoot
YDYard
LLiter
MLMilliliter
GALGallon
QTQuart
PTPint
FL_OZFluid ounce
M2Square meter
CM2Square centimeter
FT2Square foot
IN2Square inch
YD2Square yard
M3Cubic meter
CM3Cubic centimeter
FT3Cubic foot
IN3Cubic inch
YD3Cubic yard
BOXBox
CASECase
PACKPack
SETSet
KITKit
BUNDLEBundle
ROLLRoll
SHEETSheet
PALLETPallet
DRUMDrum
BAGBag
BOTTLEBottle
CENHundred
If you send an unrecognized unit, it is stored as-is. We recommend using standard codes so the AI can properly normalize supplier quotations.

Integration Flow

Typical integration pattern for a scheduled ERP sync (e.g., cron job every 15 minutes):

1

Collect new requisitions from ERP

Query your ERP for approved requisitions that haven't been synced to Sourced yet.

2

Check existing (optional)

Call POST /requisitions/check-existing with external_ids to filter out already-synced requisitions.

3

Import requisitions

Call POST /requisitions with the batch of new/updated requisitions. Store the returned requisition_ids.

4

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"}.

5

Confirm approved POs

When the PO is approved in your ERP, call POST /purchase-orders/{id}/status with {"status": "CONFIRMED"} to close the loop.

Pseudocode — Sync cron job
# 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:

Complete import request
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"
        }
      }
    ]
  }'
Response — 200 OK
{
  "success": true,
  "created_count": 1,
  "updated_count": 0,
  "skipped_count": 0,
  "error_count": 0,
  "errors": [],
  "requisition_ids": [1234]
}