curl --request POST \
--url https://api.paygentic.io/v2/invoices/lineItems \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"displayName": "<string>",
"currency": "<string>",
"quantity": 123,
"unitPrice": 123,
"subscriptionId": "<string>",
"invoiceId": "<string>",
"description": "<string>",
"invoiceAt": "2023-11-07T05:31:56Z",
"periodStart": "2023-11-07T05:31:56Z",
"periodEnd": "2023-11-07T05:31:56Z",
"idempotencyKey": "<string>",
"itemId": "<string>"
}
'import requests
url = "https://api.paygentic.io/v2/invoices/lineItems"
payload = {
"displayName": "<string>",
"currency": "<string>",
"quantity": 123,
"unitPrice": 123,
"subscriptionId": "<string>",
"invoiceId": "<string>",
"description": "<string>",
"invoiceAt": "2023-11-07T05:31:56Z",
"periodStart": "2023-11-07T05:31:56Z",
"periodEnd": "2023-11-07T05:31:56Z",
"idempotencyKey": "<string>",
"itemId": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
displayName: '<string>',
currency: '<string>',
quantity: 123,
unitPrice: 123,
subscriptionId: '<string>',
invoiceId: '<string>',
description: '<string>',
invoiceAt: '2023-11-07T05:31:56Z',
periodStart: '2023-11-07T05:31:56Z',
periodEnd: '2023-11-07T05:31:56Z',
idempotencyKey: '<string>',
itemId: '<string>'
})
};
fetch('https://api.paygentic.io/v2/invoices/lineItems', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.paygentic.io/v2/invoices/lineItems",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'displayName' => '<string>',
'currency' => '<string>',
'quantity' => 123,
'unitPrice' => 123,
'subscriptionId' => '<string>',
'invoiceId' => '<string>',
'description' => '<string>',
'invoiceAt' => '2023-11-07T05:31:56Z',
'periodStart' => '2023-11-07T05:31:56Z',
'periodEnd' => '2023-11-07T05:31:56Z',
'idempotencyKey' => '<string>',
'itemId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.paygentic.io/v2/invoices/lineItems"
payload := strings.NewReader("{\n \"displayName\": \"<string>\",\n \"currency\": \"<string>\",\n \"quantity\": 123,\n \"unitPrice\": 123,\n \"subscriptionId\": \"<string>\",\n \"invoiceId\": \"<string>\",\n \"description\": \"<string>\",\n \"invoiceAt\": \"2023-11-07T05:31:56Z\",\n \"periodStart\": \"2023-11-07T05:31:56Z\",\n \"periodEnd\": \"2023-11-07T05:31:56Z\",\n \"idempotencyKey\": \"<string>\",\n \"itemId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", 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(string(body))
}HttpResponse<String> response = Unirest.post("https://api.paygentic.io/v2/invoices/lineItems")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"displayName\": \"<string>\",\n \"currency\": \"<string>\",\n \"quantity\": 123,\n \"unitPrice\": 123,\n \"subscriptionId\": \"<string>\",\n \"invoiceId\": \"<string>\",\n \"description\": \"<string>\",\n \"invoiceAt\": \"2023-11-07T05:31:56Z\",\n \"periodStart\": \"2023-11-07T05:31:56Z\",\n \"periodEnd\": \"2023-11-07T05:31:56Z\",\n \"idempotencyKey\": \"<string>\",\n \"itemId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.paygentic.io/v2/invoices/lineItems")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"displayName\": \"<string>\",\n \"currency\": \"<string>\",\n \"quantity\": 123,\n \"unitPrice\": 123,\n \"subscriptionId\": \"<string>\",\n \"invoiceId\": \"<string>\",\n \"description\": \"<string>\",\n \"invoiceAt\": \"2023-11-07T05:31:56Z\",\n \"periodStart\": \"2023-11-07T05:31:56Z\",\n \"periodEnd\": \"2023-11-07T05:31:56Z\",\n \"idempotencyKey\": \"<string>\",\n \"itemId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"subscriptionId": "<string>",
"customerId": "<string>",
"type": "fee",
"status": "pending",
"displayName": "<string>",
"currency": "<string>",
"periodStart": "2023-11-07T05:31:56Z",
"periodEnd": "2023-11-07T05:31:56Z",
"invoiceAt": "2023-11-07T05:31:56Z",
"unitPrice": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"priceId": "<string>",
"itemId": "<string>",
"invoiceId": "<string>",
"description": "<string>",
"calculatedAt": "2023-11-07T05:31:56Z",
"quantity": "<string>",
"meteredQuantity": "<string>",
"paymentTerm": "in_advance",
"subtotal": "<string>",
"taxesTotal": "<string>",
"total": "<string>",
"estimatedMeteredQuantity": "<string>",
"estimatedSubtotal": "<string>"
}{
"id": "<string>",
"subscriptionId": "<string>",
"customerId": "<string>",
"type": "fee",
"status": "pending",
"displayName": "<string>",
"currency": "<string>",
"periodStart": "2023-11-07T05:31:56Z",
"periodEnd": "2023-11-07T05:31:56Z",
"invoiceAt": "2023-11-07T05:31:56Z",
"unitPrice": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"priceId": "<string>",
"itemId": "<string>",
"invoiceId": "<string>",
"description": "<string>",
"calculatedAt": "2023-11-07T05:31:56Z",
"quantity": "<string>",
"meteredQuantity": "<string>",
"paymentTerm": "in_advance",
"subtotal": "<string>",
"taxesTotal": "<string>",
"total": "<string>",
"estimatedMeteredQuantity": "<string>",
"estimatedSubtotal": "<string>"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}Create Manual Line Item
Create a manual line item for a billing v1 subscription. Manual line items are ad-hoc charges or credits that flow through the same collection pipeline as auto-generated items. Exactly one of subscriptionId or invoiceId must be provided.
curl --request POST \
--url https://api.paygentic.io/v2/invoices/lineItems \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"displayName": "<string>",
"currency": "<string>",
"quantity": 123,
"unitPrice": 123,
"subscriptionId": "<string>",
"invoiceId": "<string>",
"description": "<string>",
"invoiceAt": "2023-11-07T05:31:56Z",
"periodStart": "2023-11-07T05:31:56Z",
"periodEnd": "2023-11-07T05:31:56Z",
"idempotencyKey": "<string>",
"itemId": "<string>"
}
'import requests
url = "https://api.paygentic.io/v2/invoices/lineItems"
payload = {
"displayName": "<string>",
"currency": "<string>",
"quantity": 123,
"unitPrice": 123,
"subscriptionId": "<string>",
"invoiceId": "<string>",
"description": "<string>",
"invoiceAt": "2023-11-07T05:31:56Z",
"periodStart": "2023-11-07T05:31:56Z",
"periodEnd": "2023-11-07T05:31:56Z",
"idempotencyKey": "<string>",
"itemId": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
displayName: '<string>',
currency: '<string>',
quantity: 123,
unitPrice: 123,
subscriptionId: '<string>',
invoiceId: '<string>',
description: '<string>',
invoiceAt: '2023-11-07T05:31:56Z',
periodStart: '2023-11-07T05:31:56Z',
periodEnd: '2023-11-07T05:31:56Z',
idempotencyKey: '<string>',
itemId: '<string>'
})
};
fetch('https://api.paygentic.io/v2/invoices/lineItems', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.paygentic.io/v2/invoices/lineItems",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'displayName' => '<string>',
'currency' => '<string>',
'quantity' => 123,
'unitPrice' => 123,
'subscriptionId' => '<string>',
'invoiceId' => '<string>',
'description' => '<string>',
'invoiceAt' => '2023-11-07T05:31:56Z',
'periodStart' => '2023-11-07T05:31:56Z',
'periodEnd' => '2023-11-07T05:31:56Z',
'idempotencyKey' => '<string>',
'itemId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.paygentic.io/v2/invoices/lineItems"
payload := strings.NewReader("{\n \"displayName\": \"<string>\",\n \"currency\": \"<string>\",\n \"quantity\": 123,\n \"unitPrice\": 123,\n \"subscriptionId\": \"<string>\",\n \"invoiceId\": \"<string>\",\n \"description\": \"<string>\",\n \"invoiceAt\": \"2023-11-07T05:31:56Z\",\n \"periodStart\": \"2023-11-07T05:31:56Z\",\n \"periodEnd\": \"2023-11-07T05:31:56Z\",\n \"idempotencyKey\": \"<string>\",\n \"itemId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", 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(string(body))
}HttpResponse<String> response = Unirest.post("https://api.paygentic.io/v2/invoices/lineItems")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"displayName\": \"<string>\",\n \"currency\": \"<string>\",\n \"quantity\": 123,\n \"unitPrice\": 123,\n \"subscriptionId\": \"<string>\",\n \"invoiceId\": \"<string>\",\n \"description\": \"<string>\",\n \"invoiceAt\": \"2023-11-07T05:31:56Z\",\n \"periodStart\": \"2023-11-07T05:31:56Z\",\n \"periodEnd\": \"2023-11-07T05:31:56Z\",\n \"idempotencyKey\": \"<string>\",\n \"itemId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.paygentic.io/v2/invoices/lineItems")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"displayName\": \"<string>\",\n \"currency\": \"<string>\",\n \"quantity\": 123,\n \"unitPrice\": 123,\n \"subscriptionId\": \"<string>\",\n \"invoiceId\": \"<string>\",\n \"description\": \"<string>\",\n \"invoiceAt\": \"2023-11-07T05:31:56Z\",\n \"periodStart\": \"2023-11-07T05:31:56Z\",\n \"periodEnd\": \"2023-11-07T05:31:56Z\",\n \"idempotencyKey\": \"<string>\",\n \"itemId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"subscriptionId": "<string>",
"customerId": "<string>",
"type": "fee",
"status": "pending",
"displayName": "<string>",
"currency": "<string>",
"periodStart": "2023-11-07T05:31:56Z",
"periodEnd": "2023-11-07T05:31:56Z",
"invoiceAt": "2023-11-07T05:31:56Z",
"unitPrice": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"priceId": "<string>",
"itemId": "<string>",
"invoiceId": "<string>",
"description": "<string>",
"calculatedAt": "2023-11-07T05:31:56Z",
"quantity": "<string>",
"meteredQuantity": "<string>",
"paymentTerm": "in_advance",
"subtotal": "<string>",
"taxesTotal": "<string>",
"total": "<string>",
"estimatedMeteredQuantity": "<string>",
"estimatedSubtotal": "<string>"
}{
"id": "<string>",
"subscriptionId": "<string>",
"customerId": "<string>",
"type": "fee",
"status": "pending",
"displayName": "<string>",
"currency": "<string>",
"periodStart": "2023-11-07T05:31:56Z",
"periodEnd": "2023-11-07T05:31:56Z",
"invoiceAt": "2023-11-07T05:31:56Z",
"unitPrice": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"priceId": "<string>",
"itemId": "<string>",
"invoiceId": "<string>",
"description": "<string>",
"calculatedAt": "2023-11-07T05:31:56Z",
"quantity": "<string>",
"meteredQuantity": "<string>",
"paymentTerm": "in_advance",
"subtotal": "<string>",
"taxesTotal": "<string>",
"total": "<string>",
"estimatedMeteredQuantity": "<string>",
"estimatedSubtotal": "<string>"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}{
"message": "The requested resource was not found",
"error": "not_found"
}Authorizations
API key authentication
Headers
Optional idempotency key. If provided, duplicate requests with the same key return the previously created item.
255Body
Human-readable label shown on the invoice.
1 - 255ISO 4217 currency code (e.g., USD). Must match the subscription or invoice currency.
3Number of units.
Price per unit as a decimal amount (e.g., 29.99 for $29.99). Can be negative for credits or adjustments.
The subscription ID. Exactly one of subscriptionId or invoiceId must be provided.
The invoice ID to attach this item directly to. Exactly one of subscriptionId or invoiceId must be provided. The invoice must be in ACTIVE or CLOSING state.
^inv_[a-zA-Z0-9]+$Optional longer description shown on the invoice.
1000When to collect this item into an invoice. Defaults to now. Ignored when invoiceId is provided.
Start of the billing period for display purposes. Defaults to now.
End of the billing period for display purposes. Defaults to now.
Optional caller-provided idempotency key. Auto-generated if not provided.
1 - 255Optional item to tag this line with, for accounting/GL mapping. Must belong to the caller's merchant and must not be archived. A manual line has no price, so it is never reached by a later restamp — supplying it here is the only opportunity to tag it.
1Response
Idempotent retry — returns previously created item
The line item ID
The subscription this line item belongs to
The customer ID that owns this line item
The type of line item. 'discount' and 'adjustment' line items have negative subtotal/total amounts: 'discount' is a grant discount, 'adjustment' is a discount agreed on the subscription.
fee, metered, manual, discount, adjustment Whether this item is pending or already on an invoice
pending, invoiced Human-readable label shown on the invoice
ISO 4217 currency code (e.g., USD)
Start of the billing period (inclusive)
End of the billing period (exclusive)
When this line item should be collected into an invoice
Price per unit in invoice currency
When the line item was created
When the line item was last updated
The price this line was generated from, or null when the line has no originating charge. With itemId it says whether a missing tag is fixable: priceId set and itemId null means the charge was simply untagged, which tagging it and restamping resolves; both null means the line records a grant-credit purchase, which is deferred revenue and is never tagged. Any measure of outstanding mapping work must exclude the latter or it can never reach zero.
Item the line's charge was tagged with, recorded when the line was generated and not re-resolved on read. null means the charge carried no tag at that moment, the line predates item stamping, or the line has no originating charge (a grant-credit purchase) — it is an expected value, not an error. Use priceId to tell those cases apart.
The invoice ID if this item has been invoiced
Optional longer description
When metered quantity was last computed
Units sold. Null for metered lines until invoice close
Raw metered usage. Null for fee/manual lines
When the line falls due relative to the window it covers. A fee line carries its price's term; a metered line is stamped in_arrears, though metered rows predating that rule carry null. Manual, grant-discount and adjustment lines are billed on no term of their own and are null. null is listed in the enum as well as via nullable because OpenAPI 3.0 validators check the enum independently — nullable: true alone does not admit it, and createLineItem (which always returns null here) was emitting a schema-violating body.
in_advance, in_arrears, null quantity × unitPrice, before discounts and taxes. For prorated lines, may differ from quantity × unitPrice by display precision; subtotal is the authoritative billed amount. Defaults to '0.00' when not yet calculated.
Total tax amount for this line item in decimal format. Null until invoice calculation is complete
Final total after discounts and taxes. Defaults to '0.00' when not yet calculated
Real-time estimated metered usage quantity. Only present for type=metered items during an active billing period. Null for fee/manual items or when estimation is unavailable.
Real-time estimated subtotal based on current metered usage. Only present for type=metered items during an active billing period. Null for fee/manual items or when estimation is unavailable.
Was this page helpful?