> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sync2books.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create transactions

> Create expense transactions and submit them for sync to your customer's accounting software

Create expense transactions and submit them for sync to your customer's accounting software

## Overview

When you create an expense transaction, Sync2Books stores it in the database and queues it for sync to the connected accounting system. The actual synchronization happens asynchronously, allowing you to create multiple expenses efficiently.

## Prerequisites

Before creating expenses, ensure you have:

* ✅ **API Key** - Your application's API key
* ✅ **Connection ID** - A connected accounting system (QuickBooks, Xero, or Sage)
* ✅ **Account IDs** - Valid account IDs from the accounting system
* ✅ **Tax Rate IDs** - Valid tax rate IDs (if applicable)

## Create a single expense

### Endpoint

```
POST /expenses/{connectionId}
```

### Request Body

```json theme={null}
{
  "id": "expense-001",
  "type": "Payment",
  "issueDate": "2024-01-15T00:00:00Z",
  "currency": "USD",
  "currencyRate": 1,
  "merchantName": "Office Supplies Co",
  "contactRef": {
    "id": "supplier-id",
    "type": "Supplier"
  },
  "bankAccountRef": {
    "id": "bank-account-id"
  },
  "lines": [
    {
      "netAmount": 100.00,
      "taxAmount": 10.00,
      "taxRateRef": {
        "id": "tax-rate-id"
      },
      "accountRef": {
        "id": "expense-account-id"
      },
      "trackingRefs": [
        {
          "id": "tracking-category-id",
          "dataType": "trackingCategories"
        }
      ],
      "invoiceTo": {
        "id": "customer-id",
        "type": "Customer"
      }
    }
  ],
  "notes": "Office supplies for Q1 2024",
  "postAsDraft": false
}
```

### Field Descriptions

| Field            | Type              | Required | Description                                                 |
| ---------------- | ----------------- | -------- | ----------------------------------------------------------- |
| `id`             | string            | ✅        | Unique identifier for the expense (UUID format recommended) |
| `type`           | string            | ✅        | Expense type: `"Payment"` or `"DirectCost"`                 |
| `issueDate`      | string (ISO 8601) | ✅        | Date when the expense was incurred                          |
| `currency`       | string            | ✅        | Three-letter currency code (e.g., `"USD"`, `"GBP"`)         |
| `currencyRate`   | number            | ✅        | Exchange rate (usually `1` for base currency)               |
| `merchantName`   | string            | ✅        | Name of the merchant/vendor                                 |
| `contactRef`     | object            | ❌        | Reference to a supplier/customer                            |
| `bankAccountRef` | object            | ❌        | Reference to the bank account used                          |
| `lines`          | array             | ✅        | Array of expense line items                                 |
| `notes`          | string            | ❌        | Additional notes about the expense                          |
| `postAsDraft`    | boolean           | ❌        | If `true`, creates as draft in accounting system            |

### Expense Lines

Each expense line item requires:

* **`netAmount`** (number, required): Net amount before tax
* **`taxAmount`** (number, required): Tax amount
* **`taxRateRef`** (object, required): Reference to tax rate
* **`accountRef`** (object, required): Reference to expense account

Optional fields:

* **`trackingRefs`** (array): Tracking categories for reporting
* **`invoiceTo`** (object): Customer to invoice (for billable expenses)

### Example: Simple Expense

```bash theme={null}
curl -X POST "https://api.sync2books.com/expenses/{connectionId}" \
  -H "X-API-Key: sk_production_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "exp-001",
    "type": "Payment",
    "issueDate": "2024-01-15T00:00:00Z",
    "currency": "USD",
    "currencyRate": 1,
    "merchantName": "Amazon",
    "lines": [
      {
        "netAmount": 50.00,
        "taxAmount": 5.00,
        "taxRateRef": { "id": "tax-10-percent" },
        "accountRef": { "id": "office-supplies-account" }
      }
    ]
  }'
```

### Response

```json theme={null}
{
  "syncBatchId": "550e8400-e29b-41d4-a716-446655440000",
  "totalExpenses": 1
}
```

The `syncBatchId` is used to track the sync status. See [Sync transactions](/expenses-sync-transactions) for monitoring sync progress.

## Create multiple expenses (batch)

You can create multiple expenses in a single request for better efficiency:

### Request

```bash theme={null}
curl -X POST "https://api.sync2books.com/expenses/{connectionId}" \
  -H "X-API-Key: sk_production_your_api_key" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "id": "exp-001",
      "type": "Payment",
      "issueDate": "2024-01-15T00:00:00Z",
      "currency": "USD",
      "currencyRate": 1,
      "merchantName": "Amazon",
      "lines": [
        {
          "netAmount": 50.00,
          "taxAmount": 5.00,
          "taxRateRef": { "id": "tax-10-percent" },
          "accountRef": { "id": "office-supplies-account" }
        }
      ]
    },
    {
      "id": "exp-002",
      "type": "Payment",
      "issueDate": "2024-01-16T00:00:00Z",
      "currency": "USD",
      "currencyRate": 1,
      "merchantName": "Staples",
      "lines": [
        {
          "netAmount": 75.00,
          "taxAmount": 7.50,
          "taxRateRef": { "id": "tax-10-percent" },
          "accountRef": { "id": "office-supplies-account" }
        }
      ]
    }
  ]'
```

### Response

```json theme={null}
{
  "syncBatchId": "550e8400-e29b-41d4-a716-446655440000",
  "totalExpenses": 2
}
```

All expenses in the batch are processed together and share the same `syncBatchId`.

## Transaction types

### Payment

A standard expense payment. This is the most common transaction type.

```json theme={null}
{
  "type": "Payment",
  "issueDate": "2024-01-15T00:00:00Z",
  "merchantName": "Office Supplies Co",
  "lines": [...]
}
```

### DirectCost

A direct cost expense, typically used for cost of goods sold (COGS).

```json theme={null}
{
  "type": "DirectCost",
  "issueDate": "2024-01-15T00:00:00Z",
  "merchantName": "Raw Materials Supplier",
  "lines": [...]
}
```

## Expense line items

### Basic line item

```json theme={null}
{
  "netAmount": 100.00,
  "taxAmount": 10.00,
  "taxRateRef": {
    "id": "tax-rate-id"
  },
  "accountRef": {
    "id": "expense-account-id"
  }
}
```

### Line item with tracking

```json theme={null}
{
  "netAmount": 100.00,
  "taxAmount": 10.00,
  "taxRateRef": {
    "id": "tax-rate-id"
  },
  "accountRef": {
    "id": "expense-account-id"
  },
  "trackingRefs": [
    {
      "id": "tracking-category-id",
      "dataType": "trackingCategories"
    }
  ]
}
```

### Billable expense line item

```json theme={null}
{
  "netAmount": 100.00,
  "taxAmount": 10.00,
  "taxRateRef": {
    "id": "tax-rate-id"
  },
  "accountRef": {
    "id": "expense-account-id"
  },
  "invoiceTo": {
    "id": "customer-id",
    "type": "Customer"
  }
}
```

## Data model

### Expense Entity

```typescript theme={null}
{
  id: string;                    // Unique identifier
  type: "Payment" | "DirectCost";
  issueDate: string;              // ISO 8601 date
  currency: string;               // Currency code
  currencyRate: number;
  merchantName: string;
  contactRef?: {
    id: string;
    type: "Supplier" | "Customer";
  };
  bankAccountRef?: {
    id: string;
  };
  lines: ExpenseLine[];
  notes?: string;
  postAsDraft?: boolean;
}
```

### Expense Line

```typescript theme={null}
{
  netAmount: number;
  taxAmount: number;
  taxRateRef: {
    id: string;
  };
  accountRef: {
    id: string;
  };
  trackingRefs?: Array<{
    id: string;
    dataType: "trackingCategories";
  }>;
  invoiceTo?: {
    id: string;
    type: "Customer";
  };
}
```

## Getting reference IDs

Before creating expenses, you need valid IDs from your accounting system. See [Map transactions](/expenses-map-transactions) for details on retrieving account, tax rate, supplier, and customer IDs.

## Error handling

### Validation errors

If required fields are missing or invalid:

```json theme={null}
{
  "statusCode": 400,
  "message": ["id should not be empty", "currency must be a string"],
  "error": "Bad Request"
}
```

### Invalid reference IDs

If a reference ID doesn't exist in the accounting system, the sync will fail. Check the sync batch status for error details.

## Best practices

1. **Use UUIDs for expense IDs** - Ensures uniqueness across your system
2. **Batch multiple expenses** - More efficient than individual requests
3. **Validate data before sending** - Ensure all required fields are present
4. **Use company-level defaults** - Reduce transaction complexity by setting defaults
5. **Handle errors gracefully** - Implement retry logic for transient failures

## Read next

* [Sync transactions](/expenses-sync-transactions) - Learn how to track sync status
* [Upload receipts](/expenses-upload-receipts) - Attach files to expenses
* [Map transactions](/expenses-map-transactions) - Configure expense mapping preferences
