> This page is for Developers.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://zuora.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://zuora.ferndocs.com/_mcp/server.

# Split an invoice

PUT https://rest.test.zuora.com/v1/invoices/{invoiceKey}/split
Content-Type: application/json

Splits a draft invoice into 2 to 20 invoices based on specified amounts or percentages.  The source invoice must be in Draft status. For amount-based splits, the sum of all split  amounts must exactly equal the original invoice total, and each split amount must be at least  the minimum currency unit. For percentage-based splits, the sum of all split percentages must  be exactly 100, up to 9 decimal places. Zuora distributes charges, discounts, tax amounts, and  tax-exempt amounts proportionally across split invoices and uses a Largest Remainder algorithm  to ensure precise rounding at both the line and invoice levels.

In exclusive-tax mode, split amounts can be specified excluding tax, with tax calculated at posting,  or including tax when draft tax is calculated. In inclusive-tax mode, split amounts always represent  tax-inclusive invoice totals, with embedded tax distributed proportionally.

For invoices with a large number of invoice items, this operation might be processed asynchronously. Use the  `jobStatus` field in the response to determine the job status:
- If `jobStatus` is `Completed`, the operation has finished and the response contains the result.
- If `jobStatus` is `Pending`, the operation is still in progress, and you must retrieve the job status later  to confirm completion.

Reference: https://zuora.ferndocs.com/developers/api-reference/zuora-api/billing-documents/invoices/split-invoice

## Authentication

- `Authorization` header (bearer token, required) — Use `Bearer {{token}}` in the `Authorization` header for authentication.

## Servers

- `https://rest.test.zuora.com` (US Developer & Central Sandbox (incl. Test Drive), default)
- `https://rest.sandbox.na.zuora.com` (US API Sandbox Cloud 1)
- `https://rest.apisandbox.zuora.com` (US API Sandbox Cloud 2)
- `https://rest.na.zuora.com` (US Production Cloud 1)
- `https://rest.zuora.com` (US Production Cloud 2)
- `https://rest.test.eu.zuora.com` (EU Developer & Central Sandbox)
- `https://rest.sandbox.eu.zuora.com` (EU API Sandbox)
- `https://rest.eu.zuora.com` (EU Production)
- `https://rest.test.ap.zuora.com` (APAC Developer & Central Sandbox)
- `https://rest.ap.zuora.com` (APAC Production)

## Request

### Path parameters

- `invoiceKey` (string, required) — The ID or number of the invoice. For example, 2c92c8955bd63cc1015bd7c151af02ab or INV-0000001.

### Headers

- `Accept-Encoding` (string, optional) — Include the `Accept-Encoding: gzip` header to compress responses as a gzipped file. It can significantly reduce the bandwidth required for a response. If specified, Zuora automatically compresses responses that contain over 1000 bytes of data, and the response contains a `Content-Encoding` header with the compression algorithm so that your client can decompress it.
- `Content-Encoding` (string, optional) — Include the `Content-Encoding: gzip` header to compress a request. With this header specified, you should upload a gzipped file for the request payload instead of sending the JSON payload.
- `Zuora-Track-Id` (string, optional) — A custom identifier for tracing the API call. If you set a value for this header, Zuora returns the same value in the response headers. This header enables you to associate your system process identifiers with Zuora API calls, to assist with troubleshooting in the event of an issue. The value of this field must use the US-ASCII character set and must not include any of the following characters: colon (`:`), semicolon (`;`), double quote (`"`), and quote (`'`).
- `Zuora-Entity-Ids` (string, optional) — An entity ID. If you have [Zuora Multi-entity](https://knowledgecenter.zuora.com/BB_Introducing_Z_Business/Multi-entity) enabled and the OAuth token is valid for more than one entity, you must use this header to specify which entity to perform the operation in. If the OAuth token is only valid for a single entity, or you do not have Zuora Multi-entity enabled, you should not set this header.
- `Zuora-Org-Ids` (string, optional) — Comma separated IDs. If you have Zuora Multi-Org enabled, you can use this header to specify which orgs to perform the operation in. If you do not have Zuora Multi-Org enabled, you should not set this header. The IDs must be a sub-set of the user's accessible orgs. If you specify an org that the user does not have access to, the operation fails. This header is important in Multi-Org (MO) setups because it defines the organization context under which the API should operate—mainly used for read access or data visibility filtering. If the header is not set, the operation is performed in scope of the user's accessible orgs.
- `Zuora-Version` (string, optional) — The minor API version. For a list of available minor versions, see [API upgrades](https://developer.zuora.com/v1-api-reference/api-upgrades/).

### Body (application/json)

This endpoint expects a SplitInvoiceRequest.

- `splitType` (enum, optional) — How the split is calculated.
  - Allowed values: `Percentage`, `Amount`
- `splits` (list of SplitInvoiceResponseSplitItems, optional) — Array of split configurations.

## Response

### 200

OK

- `success` (boolean, optional) — Indicates whether the request was successful.
- `id` (string, optional) — Unique identifier for the request.
- `jobId` (string, optional) — Identifier of the async job.
- `jobStatus` (enum, optional) — Status of the job. For invoices with a large number of invoice items, this operation might run asynchronously. In this case, the response includes `jobId` and `jobStatus`. The `jobId` identifies the operation job, and `jobStatus` indicates whether the operation is `Completed` or `Pending`. If `jobStatus` is `Pending`, use the "Retrieve an operation job" operation to check the job status until the operation is complete.
  - Allowed values: `Pending`, `Processing`, `Failed`, `Completed`
- `invoices` (list of SplitInvoiceInvoiceItems, optional) — List of generated invoices.

## Errors

### 500 Internal Server Error

Internal Server Error

- `reasons` (list of ErrorResponseReasonsItems, optional)

### 400 Client Request Error

Request Errors

- `processId` (string, optional) — The ID of the process that handles the operation.
- `reasons` (list of CommonResponseReasonsItems, optional) — The container of the error code and message. This field is available only if the `success` field is `false`.
- `requestId` (string, optional) — Unique identifier of the request.
- `success` (boolean, optional) — Indicates whether the call succeeded.

## Types

### SplitInvoiceResponseSplitItems

- `splitAmount` (double, optional) — Target invoice total amount (including tax) for this split invoice. Required when `splitType` is `Amount`. The sum of all `splitAmount` values must exactly equal the original invoice total. Each value must be at least the minimum currency unit (for example, 0.01 for USD, 1 for JPY).
- `splitPercentage` (double, optional) — Percentage of the original invoice total for this split invoice. Required when `splitType` is `Percentage`. The sum of all `splitPercentage` values must be exactly 100.000000000.
- `invoiceDate` (date, optional) — Date for the new invoice in YYYY-MM-DD format. Defaults to the original invoice date if not specified.
- `paymentTerm` (string, optional) — Payment term name for this split invoice (for example, Due Upon Receipt, Net 30). Must be a valid active payment term on the account.

### SplitInvoiceInvoiceItems

- `id` (string, optional) — Invoice ID.
- `invoiceNumber` (string, optional) — Invoice number.
- `invoiceDate` (date, optional) — Invoice date in YYYY-MM-DD format.
- `amount` (double, optional) — Invoice amount.

### ErrorResponseReasonsItems

- `code` (string, optional) — The error code of response.
- `message` (string, optional) — The detail information of the error response

### CommonResponseReasonsItems

- `code` (string, optional) — The error code of response.
- `message` (string, optional) — The detail information of the error response

## Examples

**Request**

```json
{
  "splitType": "Amount",
  "splits": [
    {
      "splitAmount": 50,
      "invoiceDate": "2026-02-01",
      "paymentTerm": "Due Upon Receipt"
    },
    {
      "splitAmount": 80,
      "invoiceDate": "2026-02-15",
      "paymentTerm": "Net 30"
    }
  ]
}
```

**Response**

```json
{
  "response": {
    "id": "8a90b9ce9cda030a019cdc3e8a455fc5",
    "invoices": [
      {
        "amount": 50,
        "id": "8a90ff929cda0319019cdc458ee6669e",
        "invoiceDate": "2026-02-01",
        "invoiceNumber": "INV00049021"
      },
      {
        "amount": 80,
        "id": "8a90ff929cda0319019cdc458ef266a1",
        "invoiceDate": "2026-02-15",
        "invoiceNumber": "INV00049022"
      }
    ],
    "jobId": "8a90ff929cda0319019cdc458e8d669c",
    "jobStatus": "Completed",
    "success": true
  }
}
```

**SDK Code**

```python Invoices_splitInvoice_example
import requests

url = "https://rest.test.zuora.com/v1/invoices/invoiceKey/split"

payload = {
    "splitType": "Amount",
    "splits": [
        {
            "splitAmount": 50,
            "invoiceDate": "2026-02-01",
            "paymentTerm": "Due Upon Receipt"
        },
        {
            "splitAmount": 80,
            "invoiceDate": "2026-02-15",
            "paymentTerm": "Net 30"
        }
    ]
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.put(url, json=payload, headers=headers)

print(response.json())
```

```javascript Invoices_splitInvoice_example
const url = 'https://rest.test.zuora.com/v1/invoices/invoiceKey/split';
const options = {
  method: 'PUT',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"splitType":"Amount","splits":[{"splitAmount":50,"invoiceDate":"2026-02-01","paymentTerm":"Due Upon Receipt"},{"splitAmount":80,"invoiceDate":"2026-02-15","paymentTerm":"Net 30"}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Invoices_splitInvoice_example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://rest.test.zuora.com/v1/invoices/invoiceKey/split"

	payload := strings.NewReader("{\n  \"splitType\": \"Amount\",\n  \"splits\": [\n    {\n      \"splitAmount\": 50,\n      \"invoiceDate\": \"2026-02-01\",\n      \"paymentTerm\": \"Due Upon Receipt\"\n    },\n    {\n      \"splitAmount\": 80,\n      \"invoiceDate\": \"2026-02-15\",\n      \"paymentTerm\": \"Net 30\"\n    }\n  ]\n}")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Invoices_splitInvoice_example
require 'uri'
require 'net/http'

url = URI("https://rest.test.zuora.com/v1/invoices/invoiceKey/split")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"splitType\": \"Amount\",\n  \"splits\": [\n    {\n      \"splitAmount\": 50,\n      \"invoiceDate\": \"2026-02-01\",\n      \"paymentTerm\": \"Due Upon Receipt\"\n    },\n    {\n      \"splitAmount\": 80,\n      \"invoiceDate\": \"2026-02-15\",\n      \"paymentTerm\": \"Net 30\"\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java Invoices_splitInvoice_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.put("https://rest.test.zuora.com/v1/invoices/invoiceKey/split")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"splitType\": \"Amount\",\n  \"splits\": [\n    {\n      \"splitAmount\": 50,\n      \"invoiceDate\": \"2026-02-01\",\n      \"paymentTerm\": \"Due Upon Receipt\"\n    },\n    {\n      \"splitAmount\": 80,\n      \"invoiceDate\": \"2026-02-15\",\n      \"paymentTerm\": \"Net 30\"\n    }\n  ]\n}")
  .asString();
```

```php Invoices_splitInvoice_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PUT', 'https://rest.test.zuora.com/v1/invoices/invoiceKey/split', [
  'body' => '{
  "splitType": "Amount",
  "splits": [
    {
      "splitAmount": 50,
      "invoiceDate": "2026-02-01",
      "paymentTerm": "Due Upon Receipt"
    },
    {
      "splitAmount": 80,
      "invoiceDate": "2026-02-15",
      "paymentTerm": "Net 30"
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Invoices_splitInvoice_example
using RestSharp;

var client = new RestClient("https://rest.test.zuora.com/v1/invoices/invoiceKey/split");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"splitType\": \"Amount\",\n  \"splits\": [\n    {\n      \"splitAmount\": 50,\n      \"invoiceDate\": \"2026-02-01\",\n      \"paymentTerm\": \"Due Upon Receipt\"\n    },\n    {\n      \"splitAmount\": 80,\n      \"invoiceDate\": \"2026-02-15\",\n      \"paymentTerm\": \"Net 30\"\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Invoices_splitInvoice_example
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "splitType": "Amount",
  "splits": [
    [
      "splitAmount": 50,
      "invoiceDate": "2026-02-01",
      "paymentTerm": "Due Upon Receipt"
    ],
    [
      "splitAmount": 80,
      "invoiceDate": "2026-02-15",
      "paymentTerm": "Net 30"
    ]
  ]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://rest.test.zuora.com/v1/invoices/invoiceKey/split")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```