# Building a Custom Integration

## Objective

Set up a custom integration that automatically syncs new transport orders to an external system (e.g., your ERP, a webhook endpoint, or a data warehouse).

## Step 1: Create the Integration


```bash
curl -X POST https://api.otms.transportial.com/api/integration \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "name": "ERP Sync - New Orders",
    "type": "configured",
    "description": "Push new transport orders to our ERP system when they are created",
    "enabled": true
  }'
```

**Response:**


```json
{
  "success": true,
  "message": "OK",
  "integration": {
    "id": "integration-uuid",
    "name": "ERP Sync - New Orders",
    "type": "configured",
    "enabled": true,
    "createdAt": "2026-03-22T10:00:00Z"
  }
}
```

## Step 2: Generate Credentials

Create authentication credentials for the integration:


```bash
curl -X POST "https://api.otms.transportial.com/api/integration/generate/credentials" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "integrationId": "integration-uuid"
  }'
```

Store the returned credentials securely — they grant access to the integration's scoped data.

## Step 3: Test Your Data Mapping

Before going live, validate that your data transformation works:


```bash
curl -X POST "https://api.otms.transportial.com/api/integration/dataSource/mapping:test" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "mapping": {
      "erp_order_id": "$.transportOrder.id",
      "customer_name": "$.transportOrder.customer.name",
      "status": "$.transportOrder.status",
      "created": "$.transportOrder.createdAt"
    },
    "testData": {
      "transportOrder": {
        "id": "test-uuid",
        "customer": { "name": "Acme Corp" },
        "status": "requested",
        "createdAt": "2026-03-22T10:00:00Z"
      }
    }
  }'
```

## Step 4: Import Data (Inbound)

If your integration needs to push data into Transportial:


```bash
curl -X POST "https://api.otms.transportial.com/api/integration/import/data" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "integrationId": "integration-uuid",
    "data": [
      {
        "name": "Order from ERP #12345",
        "status": "requested",
        "customer": { "name": "External Customer" }
      }
    ]
  }'
```

## Step 5: Monitor Processing

### Check the Processing Queue


```bash
curl -X GET "https://api.otms.transportial.com/api/integration/{integration-uuid}/objects/0/20" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### View Logs


```bash
curl -X GET "https://api.otms.transportial.com/api/integration/{integration-uuid}/logs/0/20" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Check Request Logs

See the actual HTTP requests the integration has made:


```bash
curl -X GET "https://api.otms.transportial.com/api/integration/{integration-uuid}/requestLogs/0/20" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### View Integration Tasks


```bash
curl -X GET "https://api.otms.transportial.com/api/integration/{integration-uuid}/tasks/0/20" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

## Step 6: Handle Errors

If an integration object fails, it will be marked with status `ERROR` or `RETRY`. Check the logs to diagnose:


```bash
# Get recent logs
curl -X GET "https://api.otms.transportial.com/api/integration/{integration-uuid}/logs/0/10" \
  -H "Authorization: Bearer YOUR_TOKEN"
```

Common issues:

- **Authentication failure** — regenerate credentials
- **Mapping error** — test your mapping with the test endpoint
- **Target system down** — objects will be retried automatically


## Email-Based Integration

For email-triggered workflows:


```bash
curl -X POST "https://api.otms.transportial.com/api/integration/email" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "from": "orders@customer.com",
    "subject": "New transport request",
    "body": "Please arrange pickup of 20 pallets..."
  }'
```

## File-Based Integration

Upload template files for EDI, CSV, or XML exchange:


```bash
curl -X POST "https://api.otms.transportial.com/api/integration/file/upload" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "file=@/path/to/template.csv"
```

Test file template mappings:


```bash
curl -X POST "https://api.otms.transportial.com/api/integration/fileTemplate/mapping:test" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "mapping": { ... },
    "testData": { ... }
  }'
```

## Integration Processing Flow


```
Entity Change (e.g., new transport order)
    ↓
IntegrationObject created (status: QUEUE)
    ↓
Scheduler picks up (~every 10 seconds)
    ↓
Filters checked (does this event match?)
    ↓
Data sources transform the data
    ↓
External system called
    ↓
Result: SUCCESS / ERROR / RETRY
```

## Key Takeaways

- Integrations are event-driven — they react to entity changes automatically
- Always test your mappings before enabling
- Monitor logs and request logs to diagnose issues
- Failed objects are retried automatically
- Use the App Store for pre-built integrations with common platforms