# Mosaic Integration Guide

This guide walks you through building a complete integration using Orderful's Mosaic API (v4). By the end, you'll be able to receive, process, and respond to EDI transactions.

## What is Mosaic?

Mosaic is Orderful's next-generation developer platform. It provides:

* **Simple schema**: Logical, human-friendly field names
* **ERP-oriented**: Data structures that match your business systems
* **No partner mapping**: Build once against a universal schema
* **Shorter payloads**: Context from related transactions is inherited
* **Real-time validation**: Clear, actionable error messages

***

## Prerequisites

Before starting, ensure you have:

* [ ] Completed the [Quick Start Guide](quick-start.md)
* [ ] Your API key from Settings → API Credentials
* [ ] A test trading partnership (use Integration Testing to set one up)

***

## Architecture Overview

A typical Mosaic integration follows this pattern:

```
┌─────────────────-┐     ┌─────────────┐     ┌──────────────────┐
│  Trading Partner │────▶│  Orderful   │────▶│  Your System     │
│  (Retailer)      │     │  (EDI Hub)  │     │  (ERP/WMS/OMS)   │
└────────────────-─┘     └─────────────┘     └──────────────────┘
        │                      │                     │
        │    850 (PO)          │                     │
        │─────────────────────▶│ ──── Webhook ──────▶│
        │                      │   or Polling        │
        │                      │                     │
        │    855 (POA)         │                     │
        │◀─────────────────────│ ◀─── POST  ─────    │
        │                      │                     │
        │    856 (ASN)         │                     │
        │◀─────────────────────│ ◀─── POST  ─────    │
        │                      │                     │
        │    810 (Invoice)     │                     │
        │◀─────────────────────│ ◀─── POST  ─────    │
        │                      │                     │
```

***

## Step 1: Receiving Inbound Transactions

When a trading partner sends you a transaction (like a Purchase Order), you have two options to receive it:

### Option A: Webhooks (Recommended)

Configure a webhook to receive real-time notifications:

1. Go to **Settings → Webhooks** in the Orderful portal
2. Add your endpoint URL
3. Select the events you want to receive

Your endpoint will receive payloads like:

```json
{
  "event": "transaction.created",
  "data": {
    "transactionId": 12345,
    "transactionType": "850",
    "direction": "inbound",
    "stream": "live"
  }
}
```

### Option B: Polling the Inbox

Poll the v4 inbox endpoint for new transactions:

```bash
curl -X GET "https://api.orderful.com/inbox" \
  -H "orderful-api-key: YOUR_API_KEY" \
  -H "orderful-api-version: v4"
```

**Response:**

```json
{
  "items": [
    {
      "id": 12345,
      "transactionType": "850",
      "sender": {
        "name": "Retail Corp",
        "isaId": "RETAILCORP"
      },
      "receiver": {
        "name": "Your Company",
        "isaId": "YOURCOMPANY"
      },
      "createdAt": "2026-01-15T10:30:00Z",
      "delivery": {
        "id": 67890,
        "status": "pending"
      }
    }
  ]
}
```

***

## Step 2: Get Transaction Content

Once you identify a transaction, retrieve its full content:

```bash
curl -X GET "https://api.orderful.com/v3/transactions/12345/message" \
  -H "orderful-api-key: YOUR_API_KEY"
```

**Response (850 Purchase Order - Mosaic Schema):**

```json
{
  "type": "850_PURCHASE_ORDER",
  "stream": "test",
  "senderId": "BUYERISA",
  "receiverId": "SELLERISA",
  "message": {
    "purpose": "original",
    "purchaseOrderType": "standalone",
    "purchaseOrderNumber": "PO-2024-001234",
    "purchaseOrderDate": "2024-01-15",
    "parties": {
      "buyer": {
        "name": "Acme Retail Corp",
        "identificationCode": "ACME001",
        "identificationCodeType": "senderId"
      },
      "shipTo": {
        "name": "Acme Distribution Center",
        "identificationCode": "DC-001",
        "addressLine1": "456 Warehouse Blvd",
        "city": "Indianapolis",
        "stateOrProvinceCode": "IN",
        "postalCode": "46201",
        "countryCode": "US"
      },
      "supplier": {
        "name": "Best Products Inc",
        "identificationCode": "VENDOR123",
        "identificationCodeType": "receiverId"
      }
    },
    "dates": {
      "requestedDeliveryDate": "2024-01-25"
    },
    "lineItems": [
      {
        "purchaseOrderLineId": "1",
        "quantity": {
          "value": "100",
          "unitOfMeasure": "each"
        },
        "unitCostPrice": "24.99",
        "productIds": {
          "buyerItemNumber": "SKU-12345",
          "vendorItemNumber": "VPN-98765"
        },
        "productAttributes": {
          "description": "Widget Model A - Blue"
        }
      }
    ]
  }
}
```

***

## Step 3: Confirm Delivery

After successfully processing the transaction, confirm receipt:

```bash
curl -X POST "https://{baseUrl}/transactions/12345/deliveries/67890/approve" \
  -H "orderful-api-key: YOUR_API_KEY" \
  -H "orderful-api-version: v4" \
  -H "Content-Type: application/json"
```

If there's an issue with the transaction, you can reject it:

```bash
curl -X POST "https://{baseUrl}/transactions/12345/deliveries/67890/fail" \
  -H "orderful-api-key: YOUR_API_KEY" \
  -H "orderful-api-version: v4" \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "Invalid product codes on lines 3 and 4"
  }'
```

***

## Step 4: Send a Response Transaction

### Sending a Purchase Order Acknowledgment (855)

Acknowledge the PO to your trading partner:

```bash
curl -X POST "https://{baseUrl}/transactions" \
  -H "orderful-api-key: YOUR_API_KEY" \
  -H "orderful-api-version: v4" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "855_PURCHASE_ORDER_ACKNOWLEDGEMENT",
    "senderId": "YOUR_ISA_ID",
    "receiverId": "RETAILCORP",
    "stream": "test",
    "message": {
      "purpose": "original",
      "acknowledgementType": "accepted",
      "purchaseOrderNumber": "PO-2024-001234",
      "purchaseOrderDate": "2024-01-15",
      "acknowledgementDate": "2024-01-16",
      "lineItems": [
        {
          "purchaseOrderLineId": "1",
          "itemStatusCode": "accepted",
          "quantity": {
            "value": "100",
            "unitOfMeasure": "each"
          },
          "unitCostPrice": "24.99"
        }
      ]
    }
  }'
```

<br />

### Sending an Advance Ship Notice (856)

When you ship the order, send an ASN:

```bash
curl -X POST "https://{baseUrl}/transactions" \
  -H "orderful-api-key: YOUR_API_KEY" \
  -H "orderful-api-version: v4" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "856_SHIP_NOTICE",
    "senderId": "YOUR_ISA_ID",
    "receiverId": "RETAILCORP",
    "stream": "test",
    "relatedTransactionId": 12345,
    "message": {
      "purpose": "original",
      "shipNoticeOrManifestNumber": "SHIP-2024-001",
      "shipNoticeDate": "2024-01-20",
      "parties": {
        "shipFrom": {
          "name": "Your Warehouse",
          "addressLine1": "789 Shipping Lane",
          "city": "Warehouse City",
          "stateOrProvinceCode": "TX",
          "postalCode": "75001",
          "countryCode": "US"
        }
      },
      "dates": {
        "shipDate": "2024-01-20",
        "estimatedDeliveryDate": "2024-01-25"
      },
      "carrierInformation": {
        "carrierName": "FastFreight Inc",
        "carrierSCAC": "FFRT",
        "carrierProNumber": "1Z999AA10123456784"
      },
      "packages": [
        {
          "packagingCode": "carton",
          "weight": {
            "value": "25.5",
            "unitOfMeasure": "pounds"
          },
          "lineItems": [
            {
              "purchaseOrderLineId": "1",
              "quantityShipped": {
                "value": "100",
                "unitOfMeasure": "each"
              }
            }
          ]
        }
      ]
    }
  }'
```

***

### Sending an Invoice (810)

After shipment, send the invoice:

```bash
curl -X POST "https://{baseUrl}/transactions" \
  -H "orderful-api-key: YOUR_API_KEY" \
  -H "orderful-api-version: v4" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "810_INVOICE",
    "senderId": "YOUR_ISA_ID",
    "receiverId": "RETAILCORP",
    "stream": "test",
    "relatedTransactionId": 12345,
    "message": {
      "invoiceDate": "2024-01-20",
      "invoiceNumber": "INV-2024-001234",
      "purchaseOrderNumber": "PO-2024-001234",
      "terms": {
        "termsType": "basic",
        "termsBasisDateCode": "invoiceDate",
        "termsDueDays": 30,
        "termsDescription": "NET30"
      },
      "lineItems": [
        {
          "invoiceLineId": "1",
          "quantity": {
            "value": "100",
            "unitOfMeasure": "each"
          },
          "unitPrice": "25.00",
          "productIds": {
            "vendorItemNumber": "YOUR-SKU-001"
          },
          "productAttributes": {
            "description": "Widget Type A"
          }
        }
      ],
      "summary": {
        "totalAmount": "4250.00",
        "taxAmount": "340.00",
        "grandTotal": "4590.00"
      }
    }
  }'
```

***

## Error Handling

Mosaic provides clear, actionable error messages. Here's an example validation error:

```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Transaction validation failed",
    "details": [
      {
        "field": "message.purchaseOrderAcknowledgment.lineItems[0].quantity",
        "message": "Quantity must be a positive number",
        "value": -10
      },
      {
        "field": "message.purchaseOrderAcknowledgment.purchaseOrderNumber",
        "message": "Purchase order number is required",
        "value": null
      }
    ]
  }
}
```

### Common Error Codes

| Code                     | Meaning                           | How to Fix                                          |
| ------------------------ | --------------------------------- | --------------------------------------------------- |
| `VALIDATION_ERROR`       | Request payload failed validation | Check the `details` array for specific field errors |
| `AUTHENTICATION_ERROR`   | Invalid or missing API key        | Verify your `orderful-api-key` header               |
| `RELATIONSHIP_NOT_FOUND` | No trading relationship exists    | Set up a relationship with this partner first       |
| `RATE_LIMIT_EXCEEDED`    | Too many requests                 | Implement exponential backoff                       |

***

## Best Practices

### 1. Use Related Transaction IDs

Always link response transactions (855, 856, 810) to the original PO:

```json
{
  "relatedTransactionId": 12345,
  ...
}
```

This enables Orderful to inherit context and validate against the original transaction.

### 2. Implement Idempotency

Include idempotency keys for outbound transactions:

```bash
curl -X POST "https://{baseUrl}/transactions" \
  -H "orderful-api-key: YOUR_API_KEY" \
  -H "Idempotency-Key: your-unique-key-12345" \
  ...
```

### 3. Handle Webhooks Properly

* Respond with 2xx status within 30 seconds
* Implement retry logic for failures
* Verify webhook signatures

### 4. Test in Sandbox First

Always use `"stream": "test"` during development:

```json
{
  "stream": "test",
  ...
}
```

***

## Next Steps

* **[Order to Cash Workflow](https://docs.orderful.com/reference/order-to-cash)** - Complete workflow walkthrough
* **[Mosaic Schema Reference](/reference/mosaic-schemas)** - Full schema documentation
* **[Error Handling Guide](error-handling.md)** - Comprehensive error handling
* **[Testing Guide](testing-guide.md)** - Testing strategies and tools

<br />