# Store metadata Source: https://fragment.dev/guides/store-metadata [Documentation index](https://fragment.dev/llms.txt) You can provide up to 20 tags on Ledger Entries to store arbitrary key-value pairs, like IDs from your product. ## Schema Entry tags You can define tags on Ledger Entry types in your Schema: ```json title="Schema-defined tags" { "key": "...", "chartOfAccounts": {...}, "ledgerEntries": { "types": [ { "type": "user_funds_account", "description": "Fund {{user_id}}", "lines": [ { "key": "increase_user_balance", "account": { "path": "liabilities/users:{{user_id}}/available" }, "amount": "{{funding_amount}}" }, {...other line} ], "tags": [ { "key": "user", "value": "{{user_id}}" }, { "key": "deposit_flow", "value": "{{deposit_flow_id}}" }, { "key": "deposit_flow_type", "value": "ach" } ] } ] } } ``` You can use the same parameter for both tag values and account paths. When posting a Ledger Entry, include tag values as parameters: ```graphql title="addLedgerEntry mutation" expandable mutation AddLedgerEntry( $ik: SafeString! $entry: LedgerEntryInput! ) { addLedgerEntry( ik: $ik, entry: $entry ) { __typename ... on AddLedgerEntryResult { entry { type ik tags { key value } } lines { amount description account { path } } } ... on Error { code message } } } ``` ```json title="addLedgerEntry variables with Schema-defined tags" { "ik": "fund-abc", "entry": { "ledger": { "ik": "quickstart-ledger" }, "type": "user_funds_account", "parameters": { "user_id": "user-1", "funding_amount": "200", "deposit_flow_id": "deposit-123" } } } ``` The Ledger Entry will have the tags you defined in the Schema: ```json title="addLedgerEntry response with tags" { "data": { "addLedgerEntry": { "entry": { "type": "user_funds_account", "ik": "fund-abc", "tags": [ { "key": "user", "value": "user-1" }, { "key": "deposit_flow", "value": "deposit-123" }, { "key": "deposit_flow_type", "value": "ach" } ] }, "lines": [...] } } } ``` ## Runtime Entry tags You can define tags at runtime when posting a Ledger Entry: ```json title="addLedgerEntry variables with runtime-defined tags" { "ik": "add-ledger-entry", "entry": { "ledger": { "ik": "quickstart-ledger" }, "type": "user_funds_account", "parameters": { "user_id": "testing-user", "funding_amount": "200", "deposit_flow_id": "abc" }, "tags": [ { "key": "deposit_flow_type", "value": "ach" }, { "key": "operator", "value": "alice" } ] } } ``` If you define tags both at runtime and in the Schema, the Ledger Entry will get the combined set of tags: ```json title="addLedgerEntry response with tags" { "data": { "addLedgerEntry": { "entry": { "type": "user_funds_account", "ik": "fund-abc", "tags": [ { "key": "user", "value": "user-1" }, { "key": "deposit_flow", "value": "deposit-123" }, { "key": "deposit_flow_type", "value": "ach" }, { "key": "operator", "value": "alice" } ] }, "lines": [...] } } } ``` You can specify the same tag `key` in both places only if they have the same `value`. ## Updating Entry tags In addition to tags defined in your Schema, you can add and update tags on a posted Ledger Entry. ```graphql title="updateLedgerEntry mutation" expandable mutation UpdateLedgerEntryTags( $ledgerEntry: LedgerEntryMatchInput! $update: UpdateLedgerEntryInput! ) { updateLedgerEntry( ledgerEntry: $ledgerEntry, update: $update ) { __typename ... on UpdateLedgerEntryResult { entry { type ik tags { key value } lines { nodes { amount description account { path } } } } } ... on Error { code message } } } ``` ```json title="updateLedgerEntry variables to add and update tags" { "ledgerEntry": { "ik": "a-ledger-entry", "ledger": { "ik": "quickstart-ledger" } }, "update": { "tags": [ { "key": "operator", "value": "bob" }, { "key": "supervisor", "value": "eve" } ] } } ``` This is an additive operation: - If you specify a tag that already exists, it will be updated - If you specify a new tag, it will be added - If you don't specify an existing tag, it will remain unchanged Updating tags will update the Ledger Entry in-place. It will not create a new version of the Ledger Entry. You can also remove tags from a Ledger Entry using the `tagsToRemove` field: ```json title="updateLedgerEntry variables to remove tags" { "ledgerEntry": { "ik": "a-ledger-entry", "ledger": { "ik": "quickstart-ledger" } }, "update": { "tagsToRemove": [ { "key": "operator", "value": "bob" } ] } } ``` When removing tags: - You must specify both the `key` and `value` of the tag to remove - If the tag doesn't exist, the removal will be ignored - You cannot remove and update/add the same tag in a single update call - You must provide at least one tag to remove You can combine adding/updating and removing tags in a single update: ```json title="updateLedgerEntry variables to add and remove tags" { "ledgerEntry": { "ik": "a-ledger-entry", "ledger": { "ik": "quickstart-ledger" } }, "update": { "tags": [ { "key": "supervisor", "value": "eve" } ], "tagsToRemove": [ { "key": "operator", "value": "bob" } ] } } ``` You can only update a Ledger Entry a maximum of 10 times. ## Line tags You can provide up to 20 tags on individual Ledger Lines to store arbitrary key-value pairs. Line tags are independent of entry-level tags — a Ledger Entry can have its own tags, and each of its lines can have their own tags. ### Schema-defined You can define tags on lines in your Schema. Tag values support `{{param}}` handlebars syntax, resolved at runtime from entry parameters: ```json title="Schema-defined line tags" { "key": "...", "chartOfAccounts": {...}, "ledgerEntries": { "types": [ { "type": "payment", "description": "Payment to merchant", "lines": [ { "key": "debit", "account": { "path": "assets/bank" }, "amount": "{{amount}}", "tags": [ { "key": "merchant", "value": "{{merchant_name}}" }, { "key": "category", "value": "{{category}}" } ] }, { "key": "credit", "account": { "path": "liabilities/merchant" }, "amount": "{{amount}}" } ] } ] } } ``` When posting a Ledger Entry, include tag values as parameters: ```json title="addLedgerEntry variables with line tags" { "ik": "payment-abc", "entry": { "ledger": { "ik": "quickstart-ledger" }, "type": "payment", "parameters": { "amount": "5000", "merchant_name": "acme-corp", "category": "software" } } } ``` The Ledger Entry lines will have the tags you defined: ```json title="addLedgerEntry response with line tags" { "data": { "addLedgerEntry": { "entry": { "type": "payment", "ik": "payment-abc", "tags": [] }, "lines": [ { "amount": "5000", "key": "debit", "account": { "path": "assets/bank" }, "tags": [ { "key": "merchant", "value": "acme-corp" }, { "key": "category", "value": "software" } ] }, { "amount": "5000", "key": "credit", "account": { "path": "liabilities/merchant" }, "tags": [] } ] } } } ``` When using `postLinesAs: "net_amounts"`, lines targeting the same (account, currency, tx) are aggregated into a single line. Tags from aggregated lines are merged: - Tags with different keys are combined onto the aggregated line - Tags with the same key and same value are deduplicated - Tags with the same key but different values cause a `BadRequestError` - If there are more than 20 tags after merging, the request fails with a `BadRequestError` ### Runtime When posting a [Runtime Ledger Entry](https://fragment.dev/markdown/guides/post-ledger-entries.md#runtime-entries), you can set tags on each line: ```graphql title="addLedgerEntry mutation with line tags" expandable mutation AddLedgerEntry( $ik: SafeString! $entry: LedgerEntryInput! ) { addLedgerEntry( ik: $ik, entry: $entry ) { __typename ... on AddLedgerEntryResult { entry { ik tags { key value } } lines { key amount account { path } tags { key value } } } ... on Error { code message } } } ``` ```json title="addLedgerEntry variables with runtime line tags" { "ik": "payment-abc", "entry": { "ledger": { "ik": "quickstart-ledger" }, "lines": [ { "account": { "path": "assets/bank", "ledger": { "ik": "quickstart-ledger" } }, "amount": "5000", "key": "debit", "tags": [ { "key": "merchant", "value": "acme-corp" }, { "key": "category", "value": "software" } ] }, { "account": { "path": "liabilities/merchant", "ledger": { "ik": "quickstart-ledger" } }, "amount": "-5000", "key": "credit" } ] } } ``` ### Repeated Lines When using [Repeated Lines](https://fragment.dev/markdown/guides/post-ledger-entries.md#repeated-lines), each line gets its own tag values from its array element's parameters: ```json title="Schema with repeated lines and tags" { "type": "multi-payment", "lines": [ { "key": "payment", "account": { "path": "assets/bank" }, "amount": "{{amount}}", "tags": [ { "key": "merchant", "value": "{{merchant_name}}" }, { "key": "category", "value": "{{category}}" } ], "repeated": { "key": "payments" } } ] } ``` ```json title="Parameters for repeated lines with tags" { "payments": [ { "amount": "10000", "merchant_name": "acme", "category": "software" }, { "amount": "20000", "merchant_name": "globex", "category": "hardware" } ] } ``` Each repeated line gets its own tag values: - Line 1: `merchant=acme, category=software` - Line 2: `merchant=globex, category=hardware