{"openapi":"3.1.0","info":{"title":"Tanzim API","description":"Turn raw card and bank transaction strings into structured merchant data.\n\n**Stability promise.** Everything under `/v1` is additive-only: fields are never removed, renamed or re-typed. The matching engine behind it improves continuously and `engine_version` tells you which build answered. Anything that would break a client ships as `/v2`.\n","version":"1.2.0"},"paths":{"/health":{"get":{"tags":["Meta"],"summary":"Liveness check","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/meta":{"get":{"tags":["Meta"],"summary":"Engine and data summary","operationId":"meta_meta_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Meta"}}}}}}},"/examples":{"get":{"tags":["Meta"],"summary":"Live example inputs and outputs","description":"Sample transactions run through the engine right now, so the output is always what the current build really returns. The docs pages are generated from this.","operationId":"examples_examples_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExamplesResponse"}}}}}}},"/keys":{"post":{"tags":["Keys"],"summary":"Create a test API key","description":"Self-serve and instant: no approval step. Returns the key once. Limited per IP address.","operationId":"create_key_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyCreated"}}}},"400":{"description":"The request body or a parameter is missing or malformed. `details` lists the offending fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Wait `Retry-After` seconds, then retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/me":{"get":{"tags":["Keys"],"summary":"Check your API key","description":"The quickest way to verify an integration: returns 200 if your key works.","operationId":"me_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"`missing_api_key` or `invalid_api_key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/keys/current":{"delete":{"tags":["Keys"],"summary":"Revoke the key you are using","description":"Use to rotate: create a new key, switch over, then revoke the old one. Irreversible.","operationId":"revoke_current_keys_current_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Revoked"}}}},"401":{"description":"`missing_api_key` or `invalid_api_key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/enrich":{"post":{"tags":["Enrichment"],"summary":"Enrich one transaction","description":"Identify the merchant behind a raw transaction string and return structured details.","operationId":"enrich_enrich_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichResponse"}}}},"400":{"description":"The request body or a parameter is missing or malformed. `details` lists the offending fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"`missing_api_key` or `invalid_api_key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Wait `Retry-After` seconds, then retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/enrich/batch":{"post":{"tags":["Enrichment"],"summary":"Enrich many transactions","description":"Up to 100 transactions per call. Each item counts once toward your rate limit. Results are in input order; one unmatched item never fails the whole batch.","operationId":"enrich_batch_enrich_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResponse"}}}},"400":{"description":"The request body or a parameter is missing or malformed. `details` lists the offending fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"`missing_api_key` or `invalid_api_key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Wait `Retry-After` seconds, then retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/statements/analyze":{"post":{"tags":["Statements"],"summary":"Analyse a bank or card statement","description":"Upload a statement (PDF, CSV or Excel) and get back every transaction parsed, dated, classified and enriched with merchant details, plus insights: spending by category and merchant, monthly trend, recurring payments and subscriptions, transfers, fees and cash. The file is processed in memory and never stored. `statement.confidence` and `statement.reconciliation` tell you whether the parse can be trusted: if the statement has a balance column, every row is checked against it.","operationId":"analyze_statement_file_statements_analyze_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_analyze_statement_file_statements_analyze_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalysisResponse"}}}},"400":{"description":"The request body or a parameter is missing or malformed. `details` lists the offending fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"`missing_api_key` or `invalid_api_key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Wait `Retry-After` seconds, then retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The request body is too large (1 MB for most endpoints; statements may be larger, see /v1/meta).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"415":{"description":"That file type isn't supported. Upload a PDF, CSV or Excel (.xlsx) statement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The file was read but no transactions could be extracted (for example a scanned PDF, a password-protected PDF, or a file that isn't a statement). `details[].reason` says which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]},{"APIKeyHeader":[]}]}},"/transactions/analyze":{"post":{"tags":["Statements"],"summary":"Analyse a list of transactions","description":"Same enrichment and insights as `/statements/analyze`, for transactions you already have as structured data (up to 5000). Include `balance` when you can: it makes direction detection and the self-check reliable.","operationId":"analyze_transactions_transactions_analyze_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalysisResponse"}}}},"400":{"description":"The request body or a parameter is missing or malformed. `details` lists the offending fields.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"`missing_api_key` or `invalid_api_key`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too many requests. Wait `Retry-After` seconds, then retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"The request body is too large (1 MB for most endpoints; statements may be larger, see /v1/meta).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The file was read but no transactions could be extracted (for example a scanned PDF, a password-protected PDF, or a file that isn't a statement). `details[].reason` says which.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]},{"APIKeyHeader":[]}]}}},"components":{"schemas":{"AnalysisResponse":{"properties":{"request_id":{"type":"string","title":"Request Id"},"engine_version":{"type":"string","title":"Engine Version"},"statement":{"$ref":"#/components/schemas/StatementInfo"},"transactions":{"items":{"$ref":"#/components/schemas/StatementTransaction"},"type":"array","title":"Transactions"},"insights":{"$ref":"#/components/schemas/Insights"}},"type":"object","required":["request_id","engine_version","statement","transactions","insights"],"title":"AnalysisResponse"},"BatchRequest":{"properties":{"items":{"items":{"$ref":"#/components/schemas/EnrichRequest"},"type":"array","maxItems":100,"minItems":1,"title":"Items","description":"1 to 100 transactions. Results come back in the same order."}},"type":"object","required":["items"],"title":"BatchRequest"},"BatchResponse":{"properties":{"request_id":{"type":"string","title":"Request Id"},"engine_version":{"type":"string","title":"Engine Version"},"results":{"items":{"$ref":"#/components/schemas/EnrichResult"},"type":"array","title":"Results"}},"type":"object","required":["request_id","engine_version","results"],"title":"BatchResponse"},"Body_analyze_statement_file_statements_analyze_post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"The statement file: PDF (with selectable text), CSV or Excel (.xlsx)."}},"type":"object","required":["file"],"title":"Body_analyze_statement_file_statements_analyze_post"},"CategoryCount":{"properties":{"name":{"type":"string","title":"Name"},"merchants":{"type":"integer","title":"Merchants"}},"type":"object","required":["name","merchants"],"title":"CategoryCount"},"CategoryInsight":{"properties":{"category":{"type":"string","title":"Category","description":"Merchant category; unidentified spending is grouped as `Unidentified`."},"amount":{"type":"number","title":"Amount"},"count":{"type":"integer","title":"Count"},"share":{"type":"number","title":"Share","description":"Share of total spending, 0 to 1."},"top_merchants":{"items":{"type":"string"},"type":"array","title":"Top Merchants"}},"type":"object","required":["category","amount","count","share","top_merchants"],"title":"CategoryInsight"},"CounterpartyInfo":{"properties":{"name":{"type":"string","title":"Name","description":"The other person's name with sensible capitalisation (\"RAO EHTISHAM ALI KHAN\" -> \"Rao Ehtisham Ali Khan\").","examples":["Ali Raza"]},"raw_name":{"type":"string","title":"Raw Name","description":"Exactly as printed on the statement (the account title returned by the bank's title fetch).","examples":["ALI RAZA"]},"bank":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bank","description":"The other party's bank or wallet, when the narration shows it.","examples":["HBL"]},"channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel","description":"`ibft`, `raast`, `wallet`, `transfer`, or `card` (a card payment made to a person's name)."},"direction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Direction","description":"`in` or `out`, from the wording of the narration. A statement's debit/credit is more reliable when you have it."},"confidence":{"type":"string","title":"Confidence","description":"`high` (two or more words) or `low` (a single word)."}},"type":"object","required":["name","raw_name","confidence"],"title":"CounterpartyInfo"},"CounterpartyInsight":{"properties":{"name":{"type":"string","title":"Name"},"sent":{"type":"number","title":"Sent"},"received":{"type":"number","title":"Received"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["name","sent","received","count"],"title":"CounterpartyInsight"},"EnrichRequest":{"properties":{"description":{"type":"string","maxLength":1000,"minLength":1,"title":"Description","description":"The raw transaction string exactly as it appears on the statement or card feed.","examples":["NETFLIX.COM 4029357689"]},"mcc":{"anyOf":[{"type":"string","pattern":"^\\d{4}$"},{"type":"null"}],"title":"Mcc","description":"Optional 4-digit Merchant Category Code from the card network. Used only as a fallback category when the merchant cannot be identified. `mcc_code` is accepted as an alias.","examples":["5968"]}},"type":"object","required":["description"],"title":"EnrichRequest"},"EnrichResponse":{"properties":{"input":{"type":"string","title":"Input","description":"The description you sent, echoed back (handy for batches)."},"matched":{"type":"boolean","title":"Matched","description":"True when a specific merchant was identified. Check this before using `merchant_name`."},"merchant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant Name","description":"Canonical merchant name. null when `matched` is false.","examples":["Netflix"]},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","description":"Spending category. When `matched` is false this is only set if you sent an `mcc`.","examples":["Subscriptions & OTT"]},"subcategory":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subcategory","examples":["OTT - International"]},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country","description":"ISO 3166-1 alpha-2 country the merchant operates in, where known; otherwise null.","examples":["PK"]},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url","description":"Logo/icon image URL. Checked to load when last verified; null when no working logo is known, so show your own placeholder (e.g. the merchant's initial)."},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website","examples":["https://netflix.com"]},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain","examples":["netflix.com"]},"mcc":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mcc","description":"The merchant's usual Merchant Category Code, where known.","examples":["5968"]},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence","description":"How sure Tanzim is that `merchant_name` is right, 0 to 1. It is derived from the match method and similarity score, not a calibrated probability: treat >= 0.9 as reliable and anything lower as worth a human glance. Always 0 when `matched` is false.","examples":[0.99]},"match":{"$ref":"#/components/schemas/Match"},"counterparty":{"anyOf":[{"$ref":"#/components/schemas/CounterpartyInfo"},{"type":"null"}],"description":"For person-to-person transfers whose narration names the other person (IBFT / Raast / wallet title fetch): who it is. When present, `matched` is false unless a real merchant was identified."},"request_id":{"type":"string","title":"Request Id","description":"Unique id for this request; also sent as the `X-Request-Id` header."},"engine_version":{"type":"string","title":"Engine Version","description":"Version of the matching engine + merchant data that produced this result.","examples":["3.1.0+18b095da"]}},"type":"object","required":["input","matched","confidence","match","request_id","engine_version"],"title":"EnrichResponse"},"EnrichResult":{"properties":{"input":{"type":"string","title":"Input","description":"The description you sent, echoed back (handy for batches)."},"matched":{"type":"boolean","title":"Matched","description":"True when a specific merchant was identified. Check this before using `merchant_name`."},"merchant_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant Name","description":"Canonical merchant name. null when `matched` is false.","examples":["Netflix"]},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","description":"Spending category. When `matched` is false this is only set if you sent an `mcc`.","examples":["Subscriptions & OTT"]},"subcategory":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subcategory","examples":["OTT - International"]},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country","description":"ISO 3166-1 alpha-2 country the merchant operates in, where known; otherwise null.","examples":["PK"]},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url","description":"Logo/icon image URL. Checked to load when last verified; null when no working logo is known, so show your own placeholder (e.g. the merchant's initial)."},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website","examples":["https://netflix.com"]},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain","examples":["netflix.com"]},"mcc":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mcc","description":"The merchant's usual Merchant Category Code, where known.","examples":["5968"]},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence","description":"How sure Tanzim is that `merchant_name` is right, 0 to 1. It is derived from the match method and similarity score, not a calibrated probability: treat >= 0.9 as reliable and anything lower as worth a human glance. Always 0 when `matched` is false.","examples":[0.99]},"match":{"$ref":"#/components/schemas/Match"},"counterparty":{"anyOf":[{"$ref":"#/components/schemas/CounterpartyInfo"},{"type":"null"}],"description":"For person-to-person transfers whose narration names the other person (IBFT / Raast / wallet title fetch): who it is. When present, `matched` is false unless a real merchant was identified."}},"type":"object","required":["input","matched","confidence","match"],"title":"EnrichResult"},"ErrorBody":{"properties":{"code":{"type":"string","title":"Code","examples":["invalid_api_key"]},"message":{"type":"string","title":"Message"},"request_id":{"type":"string","title":"Request Id"},"details":{"anyOf":[{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array"},{"type":"null"}],"title":"Details","description":"Per-field problems for `invalid_request`."}},"type":"object","required":["code","message","request_id"],"title":"ErrorBody"},"ErrorResponse":{"properties":{"error":{"$ref":"#/components/schemas/ErrorBody"}},"type":"object","required":["error"],"title":"ErrorResponse"},"ExampleItem":{"properties":{"description":{"type":"string","title":"Description"},"mcc":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mcc"},"note":{"type":"string","title":"Note"},"result":{"$ref":"#/components/schemas/EnrichResult"}},"type":"object","required":["description","note","result"],"title":"ExampleItem"},"ExamplesResponse":{"properties":{"engine_version":{"type":"string","title":"Engine Version"},"examples":{"items":{"$ref":"#/components/schemas/ExampleItem"},"type":"array","title":"Examples"}},"type":"object","required":["engine_version","examples"],"title":"ExamplesResponse"},"Health":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"Health"},"Identification":{"properties":{"spending_transactions":{"type":"integer","title":"Spending Transactions"},"identified_transactions":{"type":"integer","title":"Identified Transactions"},"identified_share_of_transactions":{"type":"number","title":"Identified Share Of Transactions"},"identified_share_of_spending":{"type":"number","title":"Identified Share Of Spending","description":"How much of the spending was matched to a known merchant, 0 to 1."},"unidentified_top":{"items":{"$ref":"#/components/schemas/UnidentifiedItem"},"type":"array","title":"Unidentified Top","description":"The biggest spending items Tanzim could not identify."}},"type":"object","required":["spending_transactions","identified_transactions","identified_share_of_transactions","identified_share_of_spending","unidentified_top"],"title":"Identification"},"Insights":{"properties":{"summary":{"$ref":"#/components/schemas/Summary"},"by_kind":{"items":{"$ref":"#/components/schemas/KindTotal"},"type":"array","title":"By Kind"},"categories":{"items":{"$ref":"#/components/schemas/CategoryInsight"},"type":"array","title":"Categories"},"top_merchants":{"items":{"$ref":"#/components/schemas/MerchantInsight"},"type":"array","title":"Top Merchants"},"monthly":{"items":{"$ref":"#/components/schemas/MonthInsight"},"type":"array","title":"Monthly"},"recurring":{"items":{"$ref":"#/components/schemas/RecurringInsight"},"type":"array","title":"Recurring","description":"Repeating payments (subscriptions, bills) detected from the dates and amounts."},"monthly_recurring_total":{"type":"number","title":"Monthly Recurring Total"},"largest_transactions":{"items":{"$ref":"#/components/schemas/LargeTransaction"},"type":"array","title":"Largest Transactions"},"counterparties":{"items":{"$ref":"#/components/schemas/CounterpartyInsight"},"type":"array","title":"Counterparties"},"payees":{"items":{"$ref":"#/components/schemas/PayeeInsight"},"type":"array","title":"Payees","description":"People you transact with, grouped across spellings, biggest first."},"regular_unnamed_transfers":{"items":{"$ref":"#/components/schemas/RegularTransfer"},"type":"array","title":"Regular Unnamed Transfers","description":"Repeating transfers with the same amount whose statement line names nobody: likely the same person or account. A pattern, not an identified payee."},"transfer_summary":{"$ref":"#/components/schemas/TransferSummary"},"identification":{"$ref":"#/components/schemas/Identification"}},"type":"object","required":["summary","by_kind","categories","top_merchants","monthly","recurring","monthly_recurring_total","largest_transactions","counterparties","payees","regular_unnamed_transfers","transfer_summary","identification"],"title":"Insights"},"KeyCreated":{"properties":{"key":{"type":"string","title":"Key","description":"The API key. Shown ONCE — store it now.","examples":["tz_test_..."]},"id":{"type":"string","title":"Id"},"prefix":{"type":"string","title":"Prefix","description":"First characters of the key, to recognise it later."},"environment":{"type":"string","title":"Environment","description":"`test` for now. Test keys are rate limited and their inputs are logged to improve Tanzim."},"created_at":{"type":"string","title":"Created At"},"rate_limits":{"$ref":"#/components/schemas/RateLimits"},"message":{"type":"string","title":"Message"}},"type":"object","required":["key","id","prefix","environment","created_at","rate_limits","message"],"title":"KeyCreated"},"KeyRequest":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Name","description":"What you're building (shown only to you).","examples":["My budgeting app"]},"email":{"anyOf":[{"type":"string","maxLength":254,"pattern":"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"},{"type":"null"}],"title":"Email","description":"Optional, but lets us tell you about breaking changes and quota."},"source":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Source","description":"Free-form label for where the key was requested from."}},"type":"object","title":"KeyRequest"},"KindTotal":{"properties":{"kind":{"type":"string","title":"Kind"},"count":{"type":"integer","title":"Count"},"debit_amount":{"type":"number","title":"Debit Amount"},"credit_amount":{"type":"number","title":"Credit Amount"}},"type":"object","required":["kind","count","debit_amount","credit_amount"],"title":"KindTotal"},"LargeTransaction":{"properties":{"date":{"type":"string","title":"Date"},"description":{"type":"string","title":"Description"},"amount":{"type":"number","title":"Amount"},"merchant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Merchant"},"kind":{"type":"string","title":"Kind"}},"type":"object","required":["date","description","amount","kind"],"title":"LargeTransaction"},"Match":{"properties":{"method":{"type":"string","title":"Method","description":"How the merchant was identified: `exact` (the whole string is a known name), `substring` (a known name appears inside it), `fuzzy` (a close misspelling/partial match), `mcc_fallback` (merchant unknown, category taken from the MCC you sent) or `none`.","examples":["substring"]},"matched_on":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Matched On","description":"The known name/alias that matched, normalised. Useful for debugging.","examples":["NETFLIX COM"]}},"type":"object","required":["method"],"title":"Match"},"Me":{"properties":{"key_id":{"type":"string","title":"Key Id"},"prefix":{"type":"string","title":"Prefix"},"environment":{"type":"string","title":"Environment"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"created_at":{"type":"string","title":"Created At"},"rate_limits":{"$ref":"#/components/schemas/RateLimits"},"usage":{"$ref":"#/components/schemas/Usage"}},"type":"object","required":["key_id","prefix","environment","created_at","rate_limits","usage"],"title":"Me"},"MerchantInsight":{"properties":{"name":{"type":"string","title":"Name"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"count":{"type":"integer","title":"Count"},"amount":{"type":"number","title":"Amount"},"average":{"type":"number","title":"Average"},"share":{"type":"number","title":"Share"},"first_date":{"type":"string","title":"First Date"},"last_date":{"type":"string","title":"Last Date"}},"type":"object","required":["name","count","amount","average","share","first_date","last_date"],"title":"MerchantInsight"},"Meta":{"properties":{"api_version":{"type":"string","title":"Api Version"},"contract_version":{"type":"string","title":"Contract Version"},"engine_version":{"type":"string","title":"Engine Version"},"environment":{"type":"string","title":"Environment"},"merchant_count":{"type":"integer","title":"Merchant Count","description":"Merchants with a full profile."},"alias_count":{"type":"integer","title":"Alias Count","description":"Distinct name variants the engine recognises."},"categories":{"items":{"$ref":"#/components/schemas/CategoryCount"},"type":"array","title":"Categories"},"rate_limits":{"$ref":"#/components/schemas/RateLimits"},"max_batch_size":{"type":"integer","title":"Max Batch Size"}},"type":"object","required":["api_version","contract_version","engine_version","environment","merchant_count","alias_count","categories","rate_limits","max_batch_size"],"title":"Meta"},"MonthInsight":{"properties":{"month":{"type":"string","title":"Month","description":"YYYY-MM"},"count":{"type":"integer","title":"Count"},"spending":{"type":"number","title":"Spending"},"transfers_out":{"type":"number","title":"Transfers Out"},"credits":{"type":"number","title":"Credits"},"net":{"type":"number","title":"Net"}},"type":"object","required":["month","count","spending","transfers_out","credits","net"],"title":"MonthInsight"},"PayeeInsight":{"properties":{"payee_id":{"type":"string","title":"Payee Id"},"name":{"type":"string","title":"Name","description":"The fullest spelling seen, capitalisation normalised."},"aliases":{"items":{"type":"string"},"type":"array","title":"Aliases","description":"Other spellings of the same person seen on the statement."},"banks":{"items":{"type":"string"},"type":"array","title":"Banks"},"channels":{"items":{"type":"string"},"type":"array","title":"Channels"},"sent":{"type":"number","title":"Sent","description":"Total you sent them."},"received":{"type":"number","title":"Received","description":"Total they sent you."},"sent_count":{"type":"integer","title":"Sent Count"},"received_count":{"type":"integer","title":"Received Count"},"first_date":{"type":"string","title":"First Date"},"last_date":{"type":"string","title":"Last Date"},"typical_sent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Typical Sent","description":"Median amount you send them."},"typical_interval_days":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Typical Interval Days","description":"Median days between transactions with them (needs 3 or more)."},"regular":{"type":"boolean","title":"Regular","description":"Three or more transactions across at least two months."},"relationship":{"type":"string","title":"Relationship","description":"`you pay them`, `they pay you` or `two-way`."}},"type":"object","required":["payee_id","name","aliases","banks","channels","sent","received","sent_count","received_count","first_date","last_date","regular","relationship"],"title":"PayeeInsight"},"RateLimits":{"properties":{"per_minute":{"type":"integer","title":"Per Minute"},"per_day":{"type":"integer","title":"Per Day"},"statements_per_hour":{"type":"integer","title":"Statements Per Hour","description":"Statement analyses (file uploads or /transactions/analyze calls) per hour.","default":20}},"type":"object","required":["per_minute","per_day"],"title":"RateLimits"},"Reconciliation":{"properties":{"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method","description":"`running_balance`: every row was checked against the statement's balance column."},"checked":{"type":"integer","title":"Checked","description":"Rows that could be checked against the running balance.","default":0},"matched":{"type":"integer","title":"Matched","description":"Rows whose amount and direction agree with the running balance.","default":0},"match_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Match Rate","description":"matched / checked. At or above 0.98 the parse is almost certainly right."},"opening_to_closing_difference":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Opening To Closing Difference","description":"opening balance + credits - debits - closing balance. 0 when the statement adds up."},"totals_match":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Totals Match","description":"True when opening + credits - debits equals the closing balance."}},"type":"object","title":"Reconciliation"},"RecurringInsight":{"properties":{"name":{"type":"string","title":"Name"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"frequency":{"type":"string","title":"Frequency","description":"`weekly`, `fortnightly`, `monthly`, `quarterly` or `yearly`."},"occurrences":{"type":"integer","title":"Occurrences"},"typical_amount":{"type":"number","title":"Typical Amount"},"amount_varies":{"type":"boolean","title":"Amount Varies","description":"True for bills whose amount changes month to month (electricity, phone)."},"total":{"type":"number","title":"Total"},"first_date":{"type":"string","title":"First Date"},"last_date":{"type":"string","title":"Last Date"},"next_expected":{"type":"string","title":"Next Expected"},"monthly_cost":{"type":"number","title":"Monthly Cost","description":"Typical amount converted to a per-month figure."},"confidence":{"type":"string","title":"Confidence"},"likely_subscription":{"type":"boolean","title":"Likely Subscription"}},"type":"object","required":["name","frequency","occurrences","typical_amount","amount_varies","total","first_date","last_date","next_expected","monthly_cost","confidence","likely_subscription"],"title":"RecurringInsight"},"RegularTransfer":{"properties":{"direction":{"type":"string","title":"Direction","description":"`debit` (you send) or `credit` (you receive)."},"amount":{"type":"number","title":"Amount"},"count":{"type":"integer","title":"Count"},"total":{"type":"number","title":"Total"},"first_date":{"type":"string","title":"First Date"},"last_date":{"type":"string","title":"Last Date"},"typical_interval_days":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Typical Interval Days"},"share_of_transfers":{"type":"number","title":"Share Of Transfers","description":"Share of that direction's transfers that have this exact amount."}},"type":"object","required":["direction","amount","count","total","first_date","last_date","share_of_transfers"],"title":"RegularTransfer"},"Revoked":{"properties":{"revoked":{"type":"boolean","title":"Revoked"}},"type":"object","required":["revoked"],"title":"Revoked"},"StatementInfo":{"properties":{"format":{"type":"string","title":"Format","description":"`csv`, `xlsx`, `pdf` or `json`."},"filename":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Filename"},"currency":{"type":"string","title":"Currency"},"transactions":{"type":"integer","title":"Transactions","description":"Transactions extracted."},"rows_read":{"type":"integer","title":"Rows Read"},"rows_skipped":{"type":"integer","title":"Rows Skipped","description":"Rows that were not transactions (totals, headers, notes) or could not be read."},"confidence":{"type":"string","title":"Confidence","description":"How much to trust the parse: `high`, `medium` or `low`. `high` means the statement's own balances check out."},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings","description":"Human-readable problems found while parsing. Show them to the user."},"period_start":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period Start"},"period_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period End"},"reconciliation":{"anyOf":[{"$ref":"#/components/schemas/Reconciliation"},{"type":"null"}],"description":"Self-check against the statement's balances. null when the statement has no balance column."}},"type":"object","required":["format","currency","transactions","rows_read","rows_skipped","confidence","warnings"],"title":"StatementInfo"},"StatementTransaction":{"properties":{"index":{"type":"integer","title":"Index","description":"Position in the statement, starting at 0."},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date"},"description":{"type":"string","title":"Description"},"amount":{"type":"number","title":"Amount","description":"Always positive; see `direction`."},"direction":{"type":"string","title":"Direction","description":"`debit` (money out), `credit` (money in) or `unknown`."},"balance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Balance"},"kind":{"type":"string","title":"Kind","description":"What sort of transaction this is: `merchant`, `transfer_in`, `transfer_out` (person-to-person), `cash`, `fee`, `income`, `interest`, `refund`, `bill_payment` or `unknown`."},"counterparty":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Counterparty","description":"The other person in a transfer, when the narration names them (capitalisation normalised)."},"payee_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payee Id","description":"Stable id of that person within this statement: different spellings of one name share it."},"counterparty_bank":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Counterparty Bank","description":"The other person's bank or wallet, when shown."},"channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel","description":"`ibft`, `raast`, `wallet`, `transfer` or `card`."},"identified":{"type":"boolean","title":"Identified","description":"True when the merchant was identified with confidence of at least 0.9. Weaker guesses stay in `enrichment` (show them as \"possibly ...\") but are not used for categories, merchants or kinds."},"enrichment":{"$ref":"#/components/schemas/EnrichResult","description":"The same result `POST /v1/enrich` returns for this narration."}},"type":"object","required":["index","description","amount","direction","kind","identified","enrichment"],"title":"StatementTransaction"},"Summary":{"properties":{"currency":{"type":"string","title":"Currency"},"transaction_count":{"type":"integer","title":"Transaction Count"},"period_start":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period Start"},"period_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period End"},"days":{"type":"integer","title":"Days"},"total_debits":{"type":"number","title":"Total Debits","description":"All money out, including transfers."},"total_credits":{"type":"number","title":"Total Credits"},"net":{"type":"number","title":"Net","description":"total_credits - total_debits."},"spending":{"type":"number","title":"Spending","description":"Money out excluding person-to-person transfers."},"transfers_out":{"type":"number","title":"Transfers Out"},"transfers_in":{"type":"number","title":"Transfers In"},"income":{"type":"number","title":"Income","description":"Credits recognised as salary/payroll."},"average_daily_spending":{"type":"number","title":"Average Daily Spending"},"average_transaction":{"type":"number","title":"Average Transaction","description":"Average spending transaction."}},"type":"object","required":["currency","transaction_count","days","total_debits","total_credits","net","spending","transfers_out","transfers_in","income","average_daily_spending","average_transaction"],"title":"Summary"},"TransactionIn":{"properties":{"date":{"type":"string","title":"Date","description":"Transaction date: 2026-01-31, 31/01/2026 (day first), 31-Jan-2026 and similar are understood.","examples":["2026-01-31"]},"description":{"type":"string","maxLength":1000,"minLength":1,"title":"Description","description":"The narration exactly as the statement shows it.","examples":["POS/KHAADI PKG MALL LHR PK"]},"amount":{"anyOf":[{"type":"number"},{"type":"string"}],"title":"Amount","description":"Amount. A number (negative = debit when `direction` is omitted) or text such as \"1,250.00 Dr\" or \"(1,250.00)\".","examples":[1250.0]},"direction":{"anyOf":[{"type":"string","enum":["debit","credit"]},{"type":"null"}],"title":"Direction","description":"If you know it. Otherwise it is inferred from the sign, a Dr/Cr marker or the balance."},"balance":{"anyOf":[{"type":"number"},{"type":"string"},{"type":"null"}],"title":"Balance","description":"Running balance after this transaction, if you have it. It makes direction detection and the self-check far more reliable."}},"type":"object","required":["date","description","amount"],"title":"TransactionIn"},"TransactionsRequest":{"properties":{"transactions":{"items":{"$ref":"#/components/schemas/TransactionIn"},"type":"array","maxItems":5000,"minItems":1,"title":"Transactions"},"currency":{"anyOf":[{"type":"string","pattern":"^[A-Za-z]{3}$"},{"type":"null"}],"title":"Currency","description":"ISO currency code, used for labelling only.","default":"PKR"}},"type":"object","required":["transactions"],"title":"TransactionsRequest"},"TransferSummary":{"properties":{"transfers":{"type":"integer","title":"Transfers"},"named":{"type":"integer","title":"Named","description":"Transfers where the statement names the other person."},"named_share":{"type":"number","title":"Named Share","description":"Many statements print only a reference, not a name: when this is low, `regular_unnamed_transfers` is the useful view."}},"type":"object","required":["transfers","named","named_share"],"title":"TransferSummary"},"UnidentifiedItem":{"properties":{"description":{"type":"string","title":"Description"},"count":{"type":"integer","title":"Count"},"amount":{"type":"number","title":"Amount"}},"type":"object","required":["description","count","amount"],"title":"UnidentifiedItem"},"Usage":{"properties":{"last_24h":{"type":"integer","title":"Last 24H","description":"Transactions enriched with this key in the last 24 hours."}},"type":"object","required":["last_24h"],"title":"Usage"}},"securitySchemes":{"HTTPBearer":{"type":"http","description":"`Authorization: Bearer tz_test_...`","scheme":"bearer"},"APIKeyHeader":{"type":"apiKey","description":"Alternative to the Bearer header, for tools that can't set one.","in":"header","name":"X-API-Key"}}}}