NIPs by PolleramaCommunity NIPs, surfaced by trustConnect
npub1mgvlrnf5hm9...

NIP-INVOICING: Structured Invoicing

Published Mar 27, 2026
kind 30588

NIP-INVOICING

Structured Invoicing

draft optional

One addressable event kind for formal invoicing on Nostr. Payment recording composes with NIP-ESCROW Receipt; expense reimbursement composes with NIP-APPROVAL.

Standalone. This NIP works independently on any Nostr application. Invoices MAY be linked to NIP-ESCROW receipts for payment tracking and NIP-APPROVAL gates for expense approval, but NIP-INVOICING works independently as a billing record format.

Design principle: This event records billing state; it does not execute payments. The invoice says "you owe me X". Actual money moves on whatever rail the parties choose. Payment confirmation uses NIP-ESCROW Receipt (kind 30535). Expense reimbursement uses NIP-APPROVAL Gate (kind 30570).

Motivation

Nostr has NIP-57 for Lightning zaps and NIP-ESCROW for conditional payment coordination, but no standard mechanism for formal invoicing. Many real-world transactions require structured billing:

  • Freelance invoicing -- a designer completes a project and issues an invoice with line items for design, revisions, and stock assets, with net_14 payment terms
  • Marketplace billing -- a seller ships goods and issues an invoice with itemised products, shipping, and tax
  • Milestone payments -- a construction project requires multiple partial payments against a single invoice as work progresses
  • Expense reimbursement -- a contractor purchases materials on behalf of a client and submits an expense claim via NIP-APPROVAL with receipt evidence
  • P2P commerce -- any peer-to-peer transaction where one party needs to formally request payment with a structured breakdown

Without a standard, each invoicing application invents its own format. NIP-INVOICING provides a minimal, composable primitive that any Nostr application can adopt for structured billing.

Relationship to Existing NIPs

  • NIP-QUOTE (kind 30530): Quotes propose prices before work begins; invoices bill for completed work. A quote says "this will cost X"; an invoice says "you owe X for work delivered." They represent distinct lifecycle moments and both are needed.
  • NIP-ESCROW Receipt (kind 30535): Invoice payments use Receipt events with an e tag referencing the invoice event. This supports partial payments via multiple Receipts against the same invoice. See [Composing with NIP-ESCROW Receipt](#composing-with-nip-escrow-receipt).
  • NIP-APPROVAL (kinds 30570-30571): Expense reimbursement uses Approval Gates with expense line items and receipt evidence. The approver responds with an Approval Response. See [Composing with NIP-APPROVAL](#composing-with-nip-approval).
  • NIP-EVIDENCE (kind 30578): Receipt documentation for expense claims uses Evidence records. Expense Approval Gates reference Evidence events via e tags.
  • NIP-57 (Zaps): NIP-57 handles Lightning zap receipts for tips and donations. NIP-INVOICING handles structured billing with line items, payment terms, and partial payments. They serve different use cases: zaps are spontaneous one-click payments; invoices are formal requests with itemised breakdowns.
  • NIP-69 (Peer-to-Peer Order Events): NIP-69 defines buy/sell order matching for marketplaces. NIP-INVOICING handles the billing step after a transaction is agreed. An invoice MAY reference a NIP-69 order event via its e tag, recording the formal payment request for a matched order.

Kinds

kinddescription
30588Invoice

Kind 30588 is an addressable event (NIP-01).


Invoice (kind:30588)

Published by a provider (seller, freelancer, contractor) as a formal request for payment. An invoice contains one or more line items, each specifying a description, quantity, unit price, and tax amount. The invoice total is carried in the amount tag and MUST equal the sum of all line item totals (quantity x unit_price + tax per item), minus any discount.

Invoices are addressable; a provider can update an invoice by republishing with the same d tag (e.g. to revise line items after a recipient disputes the original).

{
  "kind": 30588,
  "pubkey": "<provider-hex-pubkey>",
  "created_at": 1709740800,
  "tags": [
    ["d", "INV-2026-0042"],
    ["t", "invoice"],
    ["e", "<originating-event-id>", "wss://relay.example.com"],
    ["invoice_number", "INV-2026-0042"],
    ["amount", "27800"],
    ["currency", "GBP"],
    ["alt", "Invoice INV-2026-0042: 27800 GBP"],
    ["line_item", "Logo design, base fee", "1", "20000", "4000"],
    ["line_item", "Two revision rounds", "2", "1500", "600"],
    ["line_item", "Stock image licence", "1", "200", "0"],
    ["p", "<requester-hex-pubkey>"],
    ["payment_terms", "net_14"],
    ["due_date", "1710950400"],
    ["tax_rate", "20"],
    ["subtotal", "23200"],
    ["tax_total", "4600"]
  ],
  "content": "",
  "id": "<32-byte-hex>",
  "sig": "<64-byte-hex>"
}

Tags:

  • d (REQUIRED): Addressable event identifier. RECOMMENDED format: a human-readable invoice number (e.g. INV-2026-0042) or an application-specific identifier.
  • t (REQUIRED): Protocol family marker. MUST be "invoice".
  • e (RECOMMENDED): References the originating event -- a NIP-15 marketplace order, a NIP-99 classified listing, a service agreement, or any application-specific event. Invoices for work agreed off-platform MAY omit the e tag.
  • invoice_number (REQUIRED): Human-readable sequential invoice identifier for the provider's accounting records. MUST be a non-empty string.
  • amount (REQUIRED): Total invoice amount in smallest currency unit (pence for GBP, cents for USD, satoshis for SAT).
  • currency (REQUIRED): ISO 4217 currency code or cryptocurrency code (e.g. GBP, USD, EUR, SAT, BTC).
  • line_item (REQUIRED, multiple): Repeatable -- one tag per billable entry. Format: ["line_item", "<description>", "<quantity>", "<unit_price>", "<tax>"]. See [Line Item Format](#line-item-format) below.
  • p (RECOMMENDED): Invoice recipient's hex pubkey.
  • payment_terms (RECOMMENDED): Payment terms code (see [Payment Terms Codes](#payment-terms-codes) below).
  • due_date (RECOMMENDED): Payment due date as a Unix timestamp.
  • tax_rate (OPTIONAL): Applicable tax rate as a percentage string (e.g. "20" for 20%).
  • ref (OPTIONAL): External business reference (e.g. purchase order number, project code).
  • subtotal (OPTIONAL): Pre-tax subtotal in smallest currency unit.
  • tax_total (OPTIONAL): Total tax amount in smallest currency unit.
  • discount (OPTIONAL): Discount amount in smallest currency unit.
  • discount_reason (OPTIONAL): Reason for discount (e.g. "early_payment", "loyalty").
  • notes (OPTIONAL): Additional invoice notes.
  • expiration (OPTIONAL): Invoice validity period -- Unix timestamp. Clients SHOULD use NIP-40 expiration for relay-level enforcement.

Content: Empty string or NIP-44 encrypted JSON with extended invoice details such as provider business address, recipient billing address, bank details, or regulatory information.

Line Item Format

Each line_item tag is a structured multi-value tag array with positional elements:

["line_item", "<description>", "<quantity>", "<unit_price>", "<tax>"]
PositionFieldRequiredDescription
1descriptionYesHuman-readable description of the work or item
2quantityYesNumber of units (integer or decimal string)
3unit_priceYesPrice per unit in smallest currency unit
4taxNoTax amount for this line item in smallest currency unit (default: "0")

Payment Terms Codes

CodeDescription
due_on_receiptPayment due immediately upon invoice receipt
net_7Payment due within 7 days
net_14Payment due within 14 days
net_30Payment due within 30 days
net_60Payment due within 60 days
net_90Payment due within 90 days
milestonePayment due upon milestone completion
customCustom terms (details in content)

Tag Reference

TagRequiredMultipleDescription
dMUSTNoAddressable event identifier
tMUSTNoProtocol family marker
eSHOULDNoReference to originating event
invoice_numberMUSTNoHuman-readable invoice identifier
amountMUSTNoTotal invoice amount (smallest unit)
currencyMUSTNoCurrency code
line_itemMUSTYesItemised billable entry (positional array)
pSHOULDNoInvoice recipient pubkey
payment_termsSHOULDNoPayment terms code
due_dateSHOULDNoPayment due date (Unix timestamp)
tax_rateMAYNoTax rate percentage
refMAYNoExternal business reference
subtotalMAYNoPre-tax subtotal
tax_totalMAYNoTotal tax amount
discountMAYNoDiscount amount
discount_reasonMAYNoReason for discount
notesMAYNoAdditional invoice notes
expirationMAYNoInvoice validity period

REQ Filters

Discover invoices addressed to a specific recipient:

{"kinds": [30588], "#p": ["<recipient-hex-pubkey>"]}

Discover all invoices published by a specific provider:

{"kinds": [30588], "authors": ["<provider-hex-pubkey>"]}

Discover a specific invoice by its d tag:

{"kinds": [30588], "#d": ["INV-2026-0042"], "authors": ["<provider-hex-pubkey>"]}

Note: Tags such as invoice_number, payment_terms, line_item, and tax_rate are multi-letter tags. Standard relays index only single-letter tags (d, e, p, t). Discovery SHOULD use kinds, authors, #p, and #d filters as shown above. Multi-letter tag values are available after fetching the event and SHOULD be applied as client-side filters.


Composing with NIP-ESCROW Receipt

Invoice payments are recorded using NIP-ESCROW Payment Receipt (kind 30535) with an e tag referencing the invoice event. An invoice payment IS a payment receipt. The Receipt already carries payer, payee, amount, currency, trust_model, and settlement_proof. No new kind is needed.

Multiple Receipts MAY reference the same invoice for partial payments. The outstanding balance is calculated as:

outstanding = invoice.amount - sum(all kind:30535 amounts referencing this invoice)

Clients SHOULD display the outstanding balance alongside the invoice. The sum of all Receipt amounts for an invoice MUST NOT exceed the invoice amount.

Full Payment Example

A payer records full payment of invoice INV-2026-0042 via Lightning:

{
  "kind": 30535,
  "pubkey": "<payer-hex-pubkey>",
  "created_at": 1709740800,
  "tags": [
    ["d", "INV-2026-0042:receipt"],
    ["alt", "Payment receipt for invoice INV-2026-0042: 27800 GBP"],
    ["e", "<invoice-event-id>", "wss://relay.example.com"],
    ["payer", "<payer-hex-pubkey>"],
    ["payee", "<provider-hex-pubkey>"],
    ["amount", "27800"],
    ["currency", "GBP"],
    ["trust_model", "direct"],
    ["settlement_proof", "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]
  ],
  "content": "",
  "id": "<32-byte-hex>",
  "sig": "<64-byte-hex>"
}

The e tag references the Kind 30588 invoice event ID. The d tag RECOMMENDED format for invoice receipts is <invoice_d_tag>:receipt for full payments, or <invoice_d_tag>:receipt:<sequence> for partial payments.

Partial Payment Example (Milestone-Based)

First milestone payment of 50000 pence against a larger invoice, paid by bank transfer:

{
  "kind": 30535,
  "pubkey": "<payer-hex-pubkey>",
  "created_at": 1709740800,
  "tags": [
    ["d", "INV-2026-0099:receipt:001"],
    ["alt", "Partial payment receipt for invoice INV-2026-0099: 50000 GBP (milestone 1)"],
    ["e", "<invoice-event-id>", "wss://relay.example.com"],
    ["payer", "<payer-hex-pubkey>"],
    ["payee", "<provider-hex-pubkey>"],
    ["amount", "50000"],
    ["currency", "GBP"],
    ["trust_model", "direct"],
    ["settlement_proof", "BACS-REF-20260215-001"]
  ],
  "content": "",
  "id": "<32-byte-hex>",
  "sig": "<64-byte-hex>"
}

Second milestone payment completing the invoice:

{
  "kind": 30535,
  "pubkey": "<payer-hex-pubkey>",
  "created_at": 1709827200,
  "tags": [
    ["d", "INV-2026-0099:receipt:002"],
    ["alt", "Partial payment receipt for invoice INV-2026-0099: 50000 GBP (milestone 2)"],
    ["e", "<invoice-event-id>", "wss://relay.example.com"],
    ["payer", "<payer-hex-pubkey>"],
    ["payee", "<provider-hex-pubkey>"],
    ["amount", "50000"],
    ["currency", "GBP"],
    ["trust_model", "direct"],
    ["settlement_proof", "BACS-REF-20260301-002"]
  ],
  "content": "",
  "id": "<32-byte-hex>",
  "sig": "<64-byte-hex>"
}

Discovery

Clients discover invoice payments by querying for kind 30535 events that reference the invoice event ID:

{"kinds": [30535], "#e": ["<invoice-event-id>"]}

Composing with NIP-APPROVAL

Expense reimbursement uses NIP-APPROVAL Gate (kind 30570) with expense-specific tags. A reimbursement request IS an approval request: the requester creates an Approval Gate with line_item tags (same format as Invoice), e tags linking to NIP-EVIDENCE records for receipts, and the approver responds with an Approval Response (kind 30571).

Expense Approval Gate Example

A freelance photographer submits an expense claim for costs incurred during a commissioned shoot:

{
  "kind": 30570,
  "pubkey": "<provider-hex-pubkey>",
  "created_at": 1709740800,
  "tags": [
    ["d", "EXP-2026-0042:gate:expense_claim"],
    ["t", "approval-gate"],
    ["alt", "Expense approval gate: 8400 GBP for design project"],
    ["gate_type", "approval"],
    ["gate_authority", "<client-hex-pubkey>"],
    ["gate_status", "pending"],
    ["e", "<originating-event-id>", "wss://relay.example.com"],
    ["amount", "8400"],
    ["currency", "GBP"],
    ["line_item", "Stock images, Shutterstock licence x3", "1", "4500", "0"],
    ["line_item", "Express courier, prototype delivery", "1", "1200", "0"],
    ["line_item", "Adobe Illustrator monthly licence", "1", "2700", "0"],
    ["e", "<evidence-event-id-1>", "wss://relay.example.com"],
    ["e", "<evidence-event-id-2>", "wss://relay.example.com"],
    ["expiration", "1710950400"]
  ],
  "content": "Expense claim for design project. Receipts attached as evidence records.",
  "id": "<32-byte-hex>",
  "sig": "<64-byte-hex>"
}

Key conventions for expense Approval Gates:

  • gate_type SHOULD be "approval".
  • amount and currency tags carry the total reimbursement amount.
  • line_item tags use the same positional format as Invoice line items: ["line_item", "<description>", "<quantity>", "<unit_price>", "<tax>"]. For expenses, the quantity is typically "1" and unit_price is the expense amount.
  • e tags reference both the originating event (the transaction or agreement) and NIP-EVIDENCE records (kind 30578) for receipt documentation. Clients distinguish evidence references by resolving the referenced events.
  • The amount MUST equal the sum of all line_item amounts.

Expense Approval Response

The client approves the expense claim:

{
  "kind": 30571,
  "pubkey": "<client-hex-pubkey>",
  "created_at": 1709827200,
  "tags": [
    ["d", "EXP-2026-0042:gate:expense_claim:response:<client-hex-pubkey>"],
    ["t", "approval-response"],
    ["alt", "Expense approval response: approved for reimbursement"],
    ["e", "<gate-event-id>", "wss://relay.example.com"],
    ["decision", "approved"],
    ["p", "<provider-hex-pubkey>"]
  ],
  "content": "All receipts verified. Approved for reimbursement.",
  "id": "<32-byte-hex>",
  "sig": "<64-byte-hex>"
}

Once approved, the client records reimbursement using a NIP-ESCROW Receipt (kind 30535) referencing the Approval Gate event.

Expense Categories

Expense categories are application-defined. Common examples include:

CategoryDescription
materialsPhysical materials and supplies
travelTravel and transport costs
equipmentEquipment hire or purchase
subcontractorSub-contractor or specialist fees
permitsPermits, licences, and regulatory fees
accommodationAccommodation costs
mealsMeal and sustenance costs
otherOther costs (describe in description field)

Applications MAY define additional categories as needed for their domain.


Protocol Flow

Overview

!Invoice Lifecycle

sequenceDiagram
    participant Provider
    participant Relay
    participant Payer

    Provider->>Relay: Publish Invoice (kind 30588)
    Note right of Provider: line items, amount, payment terms
    Relay-->>Payer: Invoice notification

    Payer->>Payer: Review line items and totals

    alt Full payment
        Payer->>Relay: Publish Receipt (kind 30535, NIP-ESCROW)
        Relay-->>Provider: Payment confirmation
    else Partial payment (milestone)
        Payer->>Relay: Publish Receipt 001 (kind 30535)
        Relay-->>Provider: Partial payment recorded
        Note over Provider,Payer: Milestone 2 completes
        Payer->>Relay: Publish Receipt 002 (kind 30535)
        Relay-->>Provider: Invoice fully settled
    end

Happy Path: Invoice, Review, Pay

  Provider                       Relay                     Requester
      |                            |                            |
      |-- kind:30588 Invoice ----->|                            |
      |  (INV-2026-0042)           |                            |
      |                            |------- notification ------>|
      |                            |                            |
      |                            |  Requester reviews line    |
      |                            |  items and totals          |
      |                            |                            |
      |                            |<-- kind:30535 Receipt -----|
      |<------ notification -------|    (full amount)           |
      |                            |                            |
      |  Provider confirms receipt |                            |
      |                            |                            |

Partial Payment Flow (Milestone-Based)

  Provider                       Relay                     Requester
      |                            |                            |
      |-- kind:30588 Invoice ----->|                            |
      |  (payment_terms: milestone)|                            |
      |                            |------- notification ------>|
      |                            |                            |
      |                            |<-- kind:30535 Receipt -----|
      |<------ notification -------|    (amount: 50000,         |
      |                            |     d: INV:receipt:001)    |
      |                            |                            |
      |           ... milestone 2 completes ...                 |
      |                            |                            |
      |                            |<-- kind:30535 Receipt -----|
      |<------ notification -------|    (amount: 50000,         |
      |                            |     d: INV:receipt:002)    |
      |                            |                            |
      |  Invoice fully settled     |                            |
      |  (2 receipts)              |                            |
      |                            |                            |

Invoice Revision

  Provider                       Relay                     Requester
      |                            |                            |
      |-- kind:30588 Invoice v1 -->|                            |
      |                            |------- notification ------>|
      |                            |                            |
      |                            |  Requester disputes line   |
      |                            |  items (out of band)       |
      |                            |                            |
      |-- kind:30588 Invoice v2 -->|  (replaces v1; same d     |
      |   (revised line items)     |   tag, updated content)    |
      |                            |------- notification ------>|
      |                            |                            |
      |                            |<-- kind:30535 Receipt -----|
      |<------ notification -------|    (full amount)           |
      |                            |                            |

Expense Reimbursement with Evidence

  Provider                       Relay                     Client
      |                            |                            |
      |  Provider incurs costs     |                            |
      |  during work               |                            |
      |                            |                            |
      |-- kind:30578 Evidence ---->|  (receipt photos, scans)   |
      |                            |                            |
      |-- kind:30570 Approval ---->|                            |
      |   Gate (with line_items    |                            |
      |   and evidence refs)       |------- notification ------>|
      |                            |                            |
      |                            |  Client reviews expenses   |
      |                            |  and evidence              |
      |                            |                            |
      |                            |<-- kind:30571 Response ----|
      |<------ notification -------|    (decision: approved)    |
      |                            |                            |
      |                            |<-- kind:30535 Receipt -----|
      |<------ notification -------|    (reimbursement)         |
      |                            |                            |

Validation Rules

All validation rules for NIP-INVOICING events. Implementations MUST enforce these rules when processing invoicing events.

RuleEvent Kind(s)Requirement
V-INV-0130588 (Invoice)MUST include at least one line_item tag
V-INV-0230588 (Invoice)Each line_item tag MUST contain at least 4 elements: tag name, description, quantity, and unit_price
V-INV-0330588 (Invoice)amount MUST equal the sum of all line item totals (quantity x unit_price + tax) minus discount
V-INV-0430588 (Invoice)invoice_number MUST be a non-empty string
V-INV-0530588 (Invoice)SHOULD reference an originating event via e tag. Invoices for work agreed off-platform MAY omit it
V-INV-0630588 (Invoice)payment_terms value MUST be one of the defined codes when present
V-INV-0730588 (Invoice)due_date MUST be a valid future Unix timestamp when present
V-INV-0830535 (Receipt for invoice)e tag MUST reference a valid Kind 30588 invoice event
V-INV-0930535 (Receipt for invoice)amount MUST be a positive integer
V-INV-1030535 (Receipt for invoice)Sum of all Receipt amounts for an invoice MUST NOT exceed the invoice amount

Test Vectors

All examples use timestamp 1709740800 (2024-03-06T12:00:00Z) and placeholder hex pubkeys.

Kind 30588 -- Invoice

{
  "kind": 30588,
  "pubkey": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
  "created_at": 1709740800,
  "tags": [
    ["d", "INV-2026-0042"],
    ["t", "invoice"],
    ["alt", "Invoice INV-2026-0042: 27800 GBP"],
    ["e", "dddd4444eeee5555ffff6666aaaa1111bbbb2222cccc3333dddd4444eeee5555"],
    ["invoice_number", "INV-2026-0042"],
    ["amount", "27800"],
    ["currency", "GBP"],
    ["line_item", "Logo design, base fee", "1", "20000", "4000"],
    ["line_item", "Two revision rounds", "2", "1500", "600"],
    ["line_item", "Stock image licence", "1", "200", "0"],
    ["p", "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3"],
    ["payment_terms", "net_14"],
    ["due_date", "1710950400"],
    ["tax_rate", "20"],
    ["subtotal", "23200"],
    ["tax_total", "4600"]
  ],
  "content": "",
  "id": "<32-byte-hex>",
  "sig": "<64-byte-hex>"
}

Calculation check:

  • Line 1: 1 x 20000 + 4000 = 24000
  • Line 2: 2 x 1500 + 600 = 3600
  • Line 3: 1 x 200 + 0 = 200
  • Total: 24000 + 3600 + 200 = 27800

Kind 30535 -- Invoice Payment (Full, via Receipt)

{
  "kind": 30535,
  "pubkey": "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3",
  "created_at": 1709740800,
  "tags": [
    ["d", "INV-2026-0042:receipt"],
    ["alt", "Payment receipt for invoice INV-2026-0042: 27800 GBP"],
    ["e", "aaaa1111bbbb2222cccc3333dddd4444eeee5555ffff6666aaaa1111bbbb2222"],
    ["payer", "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3"],
    ["payee", "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"],
    ["amount", "27800"],
    ["currency", "GBP"],
    ["trust_model", "direct"],
    ["settlement_proof", "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"]
  ],
  "content": "",
  "id": "<32-byte-hex>",
  "sig": "<64-byte-hex>"
}

Kind 30535 -- Invoice Payment (Partial, Bank Transfer, via Receipt)

{
  "kind": 30535,
  "pubkey": "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3",
  "created_at": 1709740800,
  "tags": [
    ["d", "INV-2026-0099:receipt:001"],
    ["alt", "Partial payment receipt for invoice INV-2026-0099: 50000 GBP"],
    ["e", "aaaa1111bbbb2222cccc3333dddd4444eeee5555ffff6666aaaa1111bbbb2222"],
    ["payer", "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3"],
    ["payee", "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"],
    ["amount", "50000"],
    ["currency", "GBP"],
    ["trust_model", "direct"],
    ["settlement_proof", "BACS-REF-20260215-001"]
  ],
  "content": "",
  "id": "<32-byte-hex>",
  "sig": "<64-byte-hex>"
}

Kind 30570 -- Expense Approval Gate

{
  "kind": 30570,
  "pubkey": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
  "created_at": 1709740800,
  "tags": [
    ["d", "EXP-2026-0042:gate:expense_claim"],
    ["t", "approval-gate"],
    ["alt", "Expense approval gate: 8400 GBP for design project"],
    ["gate_type", "approval"],
    ["gate_authority", "b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3"],
    ["gate_status", "pending"],
    ["e", "dddd4444eeee5555ffff6666aaaa1111bbbb2222cccc3333dddd4444eeee5555"],
    ["amount", "8400"],
    ["currency", "GBP"],
    ["line_item", "Stock images, Shutterstock licence x3", "1", "4500", "0"],
    ["line_item", "Express courier, prototype delivery", "1", "1200", "0"],
    ["line_item", "Adobe Illustrator monthly licence", "1", "2700", "0"],
    ["e", "eeee1111ffff2222aaaa3333bbbb4444cccc5555dddd6666eeee1111ffff2222"],
    ["e", "ffff2222aaaa3333bbbb4444cccc5555dddd6666eeee1111ffff2222aaaa3333"],
    ["expiration", "1710950400"]
  ],
  "content": "Expense claim for design project. Receipts attached as evidence records.",
  "id": "<32-byte-hex>",
  "sig": "<64-byte-hex>"
}

Calculation check:

  • Item 1: 4500
  • Item 2: 1200
  • Item 3: 2700
  • Total: 4500 + 1200 + 2700 = 8400

Security Considerations

Invoice Fraud

Providers MUST only publish invoices for transactions they are a participant in. Clients SHOULD verify that the invoice publisher's pubkey matches a known participant in the referenced transaction. Applications MAY reject invoices from non-participants.

Double Payment

Clients tracking invoice payments MUST maintain a running total of all Kind 30535 Receipt events referencing a given invoice. The sum of amount values MUST NOT exceed the invoice amount. Clients SHOULD warn users when a payment would exceed the outstanding balance.

Expense Claim Manipulation

Expense Approval Gates without evidence references carry lower trust. Applications SHOULD require NIP-EVIDENCE records for expenses above a configurable threshold. The NIP-APPROVAL workflow provides a formal mechanism for recipients to review and approve or reject expense claims before reimbursement.

Tax Calculation Integrity

The amount tag on Kind 30588 is the authoritative total. Clients SHOULD independently verify that line item calculations match the stated total. Discrepancies SHOULD be flagged to the recipient before payment.

Multi-Currency Considerations

All amounts within a single invoice MUST be in the same currency (as specified by the currency tag). If a provider needs to bill in multiple currencies, they MUST publish separate invoices. Receipt currency SHOULD match the invoice currency; cross-currency payments require agreement between parties and MAY use the Receipt content field to document the exchange rate.


Relay Recommendations

Event KindRecommended RetentionRationale
30588 (Invoice)Long-term (application-specific)Financial record-keeping

Invoicing events are financial records. The appropriate retention period depends on the jurisdiction and application context. Applications SHOULD advise users on local record-keeping requirements. NIP-ESCROW Receipt events (kind 30535) used for invoice payments follow the retention guidance in NIP-ESCROW.


Use Cases

Freelancing and Creative Services

A graphic designer completes a branding project and publishes a Kind 30588 invoice with line items for design work, revision rounds, and stock image licences. The client pays via Lightning and records the payment with a Kind 30535 Receipt including the preimage as settlement proof.

Marketplace Commerce

A NIP-15 marketplace seller ships goods and issues a Kind 30588 invoice referencing the NIP-15 order event. Line items cover each product, shipping, and applicable tax. The buyer records payment with a Kind 30535 Receipt.

P2P Commerce

Two individuals agree on a transaction via Nostr DMs. The seller publishes a Kind 30588 invoice referencing the DM thread. The buyer pays and records the payment with a Kind 30535 Receipt. Both parties have a verifiable billing record.

Construction and Milestone Payments

A builder issues a Kind 30588 invoice with payment_terms: milestone for a renovation project. The client makes partial payments via Kind 30535 Receipts as each milestone is completed. Both parties can track the outstanding balance at any time.

Expense Reimbursement

A freelance photographer travelling for a commissioned shoot publishes NIP-EVIDENCE records for travel, accommodation, and equipment receipts. They then create a NIP-APPROVAL Gate (kind 30570) with expense line items and evidence references. The client reviews and approves via a Kind 30571 Response, then reimburses via a Kind 30535 Receipt.


Dependencies

  • NIP-01: Basic protocol flow, addressable events
  • NIP-40: Expiration timestamps (invoice validity)
  • NIP-44: Versioned encrypted payloads (private invoice details)
  • NIP-ESCROW: Payment Receipt (kind 30535) for recording invoice payments
  • NIP-APPROVAL: Approval Gate (kind 30570) and Response (kind 30571) for expense reimbursement
  • NIP-EVIDENCE: Evidence Record (kind 30578) for expense receipt documentation

Reference Implementation

No public reference implementation exists yet. Implementors SHOULD refer to the kind definitions above.

A minimal implementation requires:

  1. A Nostr client that supports addressable event publishing.
  2. Invoice rendering logic -- parsing line_item tag arrays and computing totals for display.
  3. Payment tracking -- querying Kind 30535 Receipts by e tag reference to the invoice event and computing outstanding balances.
  4. (Optional) Expense reimbursement -- creating NIP-APPROVAL Gates with expense line items and NIP-EVIDENCE references.