Skip to main content
POST
/
transform
Transform data
curl --request POST \
  --url https://api.structural.app/api/v1/transform \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "source": "procore",
  "target": "procore",
  "entity_type": "project",
  "data": {},
  "context": {}
}
'
{
  "canonical": {},
  "data": {},
  "metadata": {
    "source": "procore",
    "target": "procore",
    "entity_type": "<string>",
    "canonical_version": "1.0",
    "transformed_at": "2023-11-07T05:31:56Z",
    "request_id": "req_a1b2c3d4e5f6",
    "references": {
      "resolved": [
        {
          "field": "<string>",
          "canonical_id": "<string>",
          "platform_id": "<string>",
          "injected": true,
          "reason": "<string>"
        }
      ],
      "unresolved": [
        {
          "field": "<string>",
          "canonical_id": "<string>",
          "reason": "<string>"
        }
      ]
    }
  }
}
The stateless translation primitive. Pass in platform data, get back the canonical form and the target platform’s representation. Nothing is persisted - no database reads or writes, no fan-out to connected platforms. Use /transform when you want to:
  • Preview what a cross-platform translation looks like before committing with POST /propagate
  • Validate your data shape against Structural’s canonical model
  • Get both the canonical and target-platform views in a single call without side effects

Supported entity types

/transform accepts 9 entity types - more than /connect and /propagate (which accept 5), because it does not require entity data to be seeded first: project, customer, contract, invoice, payment, employee, time_entry, change_order, budget_line_item

The context field

Some mappers require additional context that is not present in the source data itself. The context field is an optional generic object (Record<string, unknown>) that passes through to the mapper. Procore contracts require context with a commitmentType key:
{
  "source": "procore",
  "target": "dynamics",
  "entity_type": "contract",
  "data": {
    "id": 1945782,
    "title": "Substructure Package",
    "number": "C-LEX-001",
    "status": "Approved",
    "grand_total": "8500000.00",
    "project": { "id": 341276, "name": "Lusail Boulevard Tower" },
    "vendor": { "id": 501004, "company": "Doha Infrastructure Partners WLL" },
    "description": "Raft foundation and basement levels",
    "contract_start_date": "2025-11-01",
    "contract_estimated_completion_date": "2026-06-30",
    "currency_configuration": { "currency_iso_code": "USD" }
  },
  "context": {
    "commitmentType": "WorkOrderContract"
  }
}
Valid values for commitmentType are "WorkOrderContract" and "PurchaseOrderContract". Omitting context when transforming a Procore contract results in a 422 TRANSFORM_ERROR. Dynamics contracts do not require context - the mapper handles them without additional input.

Response

The response contains three sections:
  • canonical - the platform-agnostic representation with typed IDs, money in minor units, and ISO currency codes
  • data - the target platform’s representation, ready to send to that platform’s API
  • metadata - source, target, entity type, canonical version, timestamp, and request ID. When cross-entity references were resolved (e.g., a payment referencing a project), a references object reports which references were resolved and which could not be found

Authorizations

Authorization
string
header
required

API key passed as a Bearer token. Keys are prefixed: sk_demo_* (sandbox), sk_live_* (production), sk_test_* (staging).

Body

application/json
source
enum<string>
required

Source platform

Available options:
procore,
dynamics
target
enum<string>
required

Target platform

Available options:
procore,
dynamics
entity_type
enum<string>
required

The entity type to transform. 9 types are supported. contract requires a context field when source is procore.

Available options:
project,
customer,
employee,
time_entry,
invoice,
payment,
contract,
change_order,
budget_line_item
data
object
required

The platform-native data to transform

context
object

Optional mapper context. For Procore contracts, pass {"commitmentType": "WorkOrderContract"} or {"commitmentType": "PurchaseOrderContract"}. Omitting this for Procore contracts results in a 422 error.

Response

Data transformed

canonical
object

The canonical (normalized) representation

data
object

The target platform's representation

metadata
object