List the credit movements
list_ledger_entriesGET/v1/credits/ledgerBeta
Lists every movement of the spendable credit balance and of the API bonus, newest first: charges, refunds, top-ups and corrections.
Beta. This endpoint is supported and can gain new fields. If a change would break your code, we tell you before it takes effect and list it in the changelog.
About
Use this to explain the balance that get_credits (GET /v1/credits) shows: what was charged and for which project, what came back, what was bought. Movements come newest first; send nextCursor as cursor to read older ones. Filter with period to read one calendar month; top-ups and their reversals belong to no month, so a period filter leaves them out. A movement the API bonus paid has credits 0, and fromBonus says how much the bonus moved; receiving the bonus is not a movement. The history starts when the ledger was turned on, and opening_balance movements sum up what came before. The balance that counts is the one of get_credits.
Example use
An agency that gives each client its own API key reads the credit movements at the end of each week. It adds up the charges and refunds of each keyId and puts the total in the weekly report of that client.
Endpoint
GET https://api.gpt-video.com/v1/credits/ledger- Scope
clips:read. - Rate limit 120 requests a minute for each key and 240 for each account, shared by every
readcall. See rate limits. - No
Idempotency-Key.
Parameters
Query
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | Optional | How many items to return, from 1 to 100. Defaults to 20. From 1 to 100. Default 20. |
cursor | string | Optional | The nextCursor value from the previous page. Leave it out to get the first page. From 1 to 512 characters. |
period | string | Optional | Only the movements that count on this calendar month, as YYYY-MM. Movements of the top-up alone (a top-up, its reversal, its opening balance) never match, because they belong to no month. Matches ^\d{4}-(0[1-9]|1[0-2])$. |
Request
List the latest credit movements.
curl "https://api.gpt-video.com/v1/credits/ledger?limit=10" \
-H "Authorization: Bearer $GPT_VIDEO_API_KEY"const res = await fetch("https://api.gpt-video.com/v1/credits/ledger?limit=10", {
method: "GET",
headers: {
"Authorization": `Bearer ${process.env.GPT_VIDEO_API_KEY}`,
},
});
const data = await res.json();
console.log(data);import os
import requests
r = requests.get(
"https://api.gpt-video.com/v1/credits/ledger?limit=10",
headers={
"Authorization": f"Bearer {os.environ['GPT_VIDEO_API_KEY']}",
},
)
data = r.json()
print(data){
"method": "tools/call",
"params": {
"name": "list_ledger_entries",
"arguments": {
"limit": 10
}
}
}Response
A successful call answers HTTP 200.
Fields to check
| Name | Type | Description |
|---|---|---|
data[].id | string | The id of the movement. It starts with lgr_. |
hasMore | boolean | true when there are more items after this page. |
nextCursor | string or null | Send it as cursor to get the next page. It is null on the last page. |
Response example
{
"data": [
{
"id": "lgr_9b1e4c7a2d5f40e8a316",
"kind": "charge",
"operation": "analysis",
"credits": -30,
"fromPlan": -30,
"fromTopUp": 0,
"fromBonus": 0,
"projectId": "prj_7c2e9a4f1b3d4e8096a5",
"source": "api",
"keyId": "mck_5f2c9e1a7b3d8046",
"period": "2026-09",
"createdAt": "2026-09-01T09:10:00.000Z"
},
{
"id": "lgr_2c8f0a6e4b1d47c9e5a0",
"kind": "top_up",
"operation": null,
"credits": 250,
"fromPlan": 0,
"fromTopUp": 250,
"fromBonus": 0,
"projectId": null,
"source": "system",
"keyId": null,
"period": null,
"createdAt": "2026-09-01T08:30:00.000Z"
}
],
"hasMore": false,
"nextCursor": null
}All response fields
| Name | Type | Required | Description |
|---|---|---|---|
data | array of objects | Required | The items of this page. |
data[].id | string | Required | The id of the movement. It starts with lgr_. |
data[].kind | string | Required | What moved the balance: charge spent credits; refund gave credits back for work that was not done or an action you undid; top_up added credits you bought; top_up_reversal took back a top-up that was refunded or disputed; plan_change corrected the month after a change of plan; adjustment is any other correction; opening_balance is the balance the history starts from. One of charge, refund, top_up, top_up_reversal, plan_change, adjustment, opening_balance. |
data[].operation | string or null | Required | What a charge paid for, and for a refund to the API bonus what the refunded charge had paid for: analysis finds the clips of a video, editing adds a clip to an edit, generation makes a video with a model, export renders a composition to a file, assistant is a turn of the Editor Assistant, tool is a voiceover, an audio separation or a brainstorm, fake_text writes a fake text story or makes its voices. null when the movement names no purchase. One of analysis, editing, generation, export, assistant, tool, fake_text. |
data[].credits | integer | Required | How the spendable balance changed: negative when credits were spent, positive when they came in. credits is fromPlan plus fromTopUp; fromBonus moves only the API bonus, so a movement the bonus paid has credits 0. |
data[].fromPlan | integer | Required | The part of credits that moved the plan credits of period. |
data[].fromTopUp | integer | Required | The part of credits that moved the top-up. |
data[].fromBonus | integer | Required | How the API bonus changed: negative when the bonus paid, positive when credits went back to it. 0 when the bonus was not involved. Receiving the bonus is not a movement: get_credits (GET /v1/credits) shows it. |
data[].projectId | string or null | Required | The project the movement is about, when it is about one; always null for generation. |
data[].source | string | Required | Where the movement came from: app is the GPT-Video app, api is a call with a key or from a connected assistant, system is everything else, such as a purchase or a plan change. One of app, api, system. |
data[].keyId | string or null | Required | The id of the API key that made the call, when a key made it, also through an assistant set up with a key. It starts with mck_. null otherwise: the GPT-Video app, a purchase, or an assistant connected without a key. |
data[].period | string or null | Required | The calendar month the movement counts on, as YYYY-MM; null for a movement of the top-up alone (a top-up, its reversal, its opening balance), which belongs to no month. |
data[].createdAt | string | Required | An ISO 8601 time in UTC. |
hasMore | boolean | Required | true when there are more items after this page. |
nextCursor | string or null | Required | Send it as cursor to get the next page. It is null on the last page. |
More examples
List the movements of one month
GET /v1/credits/ledger?period=2026-09
{
"data": [
{
"id": "lgr_9b1e4c7a2d5f40e8a316",
"kind": "charge",
"operation": "analysis",
"credits": -30,
"fromPlan": -30,
"fromTopUp": 0,
"fromBonus": 0,
"projectId": "prj_7c2e9a4f1b3d4e8096a5",
"source": "api",
"keyId": "mck_5f2c9e1a7b3d8046",
"period": "2026-09",
"createdAt": "2026-09-01T09:10:00.000Z"
}
],
"hasMore": false,
"nextCursor": null
}List what the API bonus paid
GET /v1/credits/ledger
{
"data": [
{
"id": "lgr_5d8a2f0c7e1b46a9d3c7",
"kind": "charge",
"operation": "export",
"credits": 0,
"fromPlan": 0,
"fromTopUp": 0,
"fromBonus": -1,
"projectId": null,
"source": "api",
"keyId": "mck_5f2c9e1a7b3d8046",
"period": "2026-09",
"createdAt": "2026-09-01T09:42:00.000Z"
},
{
"id": "lgr_0f6c3b9e2a7d41f8c5b1",
"kind": "charge",
"operation": "assistant",
"credits": 0,
"fromPlan": 0,
"fromTopUp": 0,
"fromBonus": -2,
"projectId": null,
"source": "api",
"keyId": "mck_5f2c9e1a7b3d8046",
"period": "2026-09",
"createdAt": "2026-09-01T09:40:00.000Z"
}
],
"hasMore": false,
"nextCursor": null
}Send a cursor that was not issued
GET /v1/credits/ledger?cursor=bm90LWEtY3Vyc29y
{
"error": {
"code": "VALIDATION_FAILED",
"message": "The cursor is not valid. Send the nextCursor of the previous page unchanged, or leave it out.",
"hint": "Fix the request as the message says, then send it again.",
"requestId": "req_7d2a9c4e1b6f3a0d8e5c2b71"
}
}Errors
Every call can also answer these errors. VALIDATION_FAILED, UNKNOWN_PARAMETER, UNAUTHORIZED, SCOPE_MISSING, RATE_LIMITED, INTERNAL, UNAVAILABLE.
Cost
No credits are used.
Related operations
get_credits(GET /v1/credits) Get the credit balance
Questions
Why is a top-up missing when I filter by month?
Top-ups and their reversals belong to no month, so a period filter leaves them out. Read the list without period to see them.
Does the sum of the movements give my balance?
Use get_credits (GET /v1/credits) for the balance. This list explains how it moved, and it is in beta while it runs next to the counters it explains.
Why does a movement have no keyId?
keyId names the API key that made the call. Movements made in the GPT-Video app, by a purchase, or by an assistant connected without a key have none.
Why is there no movement for the API bonus I received?
Receiving the bonus does not change the spendable balance. get_credits (GET /v1/credits) shows the bonus, and every charge it pays is listed here with credits 0 and the amount in fromBonus.