{"openapi":"3.1.0","info":{"title":"POST /api/v1/credit/sandbox/partner-export","version":"1.0.0","description":"Seed the sandbox from a partner export"},"servers":[{"url":"https://api.ondayzero.com","description":"Production"}],"paths":{"/api/v1/credit/sandbox/partner-export":{"post":{"tags":["credit"],"summary":"Seed the sandbox from a partner export","description":"Sandbox only. `multipart/form-data` with a `transactions` file and optional `merchants` and `payments` files (DynamoDB export or scan output, a JSON list, or a CSV), or a `pull_id` from `POST /credit/sandbox/partner-pulls` in their place (both, or neither, is `CREDIT_684`; `roles` says which table of the pull is which when it could not be worked out), the `program_id` to seed, and an optional `mapping` (JSON naming the partner's fields, or `auto`). Returns the plan as figures and as text, and warnings for any value that looks like a real person's email or phone number. A dry run unless `dry_run` is `false`; then the book is written through the same services as the seeder script (a line per merchant, settlements, payments, month-ends closed and interest accrued through `as_of`). Applying is refused while warnings stand unless `allow_unredacted` is `true` with a `reason`, which is logged and audited.","operationId":"credit_seed_partner_export","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-business-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Business-Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_credit_seed_partner_export_api_v1_credit_sandbox_partner_export_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope_PartnerExportResponse_"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"example":{"error":"validation_error","message":"Validation failed: due_date: Input should be a valid date","errors":{"due_date":"Input should be a valid date"},"code":"GEN_002","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business","content":{"application/json":{"example":{"error":"unauthorized","message":"Authentication required","code":"AUTH_001","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"example":{"error":"forbidden","message":"You don't have permission to access this resource","code":"AUTH_002","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource does not exist","content":{"application/json":{"example":{"error":"not_found","message":"Resource not found","code":"NOT_FOUND_001","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"validation_error","message":"Validation failed: amount: Input should be a valid integer","errors":{"amount":"Input should be a valid integer"},"code":"GEN_002","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"}}}}},"x-fastapi-operation-id":"credit_seed_partner_export_api_v1_credit_sandbox_partner_export_post"}}},"components":{"schemas":{"Body_credit_seed_partner_export_api_v1_credit_sandbox_partner_export_post":{"properties":{"transactions":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Transactions","description":"Card transactions export. Omitted with `pull_id`."},"merchants":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Merchants","description":"Merchants export."},"payments":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Payments","description":"Repayments export."},"pull_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pull Id","description":"A registered pull to seed from, instead of uploaded files."},"roles":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Roles","description":"With `pull_id`: JSON of role to table name, e.g. {\"transactions\": \"tie-transactions\"}. Overrides the pull roles."},"program_id":{"type":"string","title":"Program Id","description":"The program to seed."},"mapping":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mapping","description":"JSON naming the partner's fields, e.g. {\"transactions\": {\"amount_cents\": \"amount\"}}. Omitted: the default names."},"as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of","description":"Close month-ends and accrue through this date. Default today."},"dry_run":{"type":"boolean","title":"Dry Run","description":"Plan only; write nothing. Default true.","default":true},"allow_unredacted":{"type":"boolean","title":"Allow Unredacted","description":"Apply even with warnings. Needs `reason`.","default":false},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Why un-redacted data may be seeded. Logged and audited."}},"type":"object","required":["program_id"],"title":"Body_credit_seed_partner_export_api_v1_credit_sandbox_partner_export_post"},"PartnerExportCounts":{"properties":{"lines_created":{"type":"integer","title":"Lines Created","description":"Credit lines opened."},"lines_reused":{"type":"integer","title":"Lines Reused","description":"Merchants that already had a line on the program."},"settlements":{"type":"integer","title":"Settlements","description":"Settlements accepted."},"duplicates":{"type":"integer","title":"Duplicates","description":"Settlements already on the book."},"payments":{"type":"integer","title":"Payments","description":"Payments recorded."}},"type":"object","required":["lines_created","lines_reused","settlements","duplicates","payments"],"title":"PartnerExportCounts"},"PartnerExportPlan":{"properties":{"merchant_count":{"type":"integer","title":"Merchant Count","description":"Merchants: one credit line each."},"transaction_count":{"type":"integer","title":"Transaction Count","description":"Card transactions to settle."},"payment_count":{"type":"integer","title":"Payment Count","description":"Repayments to record."},"first_day":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"First Day","description":"The earliest transaction or payment date."},"last_day":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Last Day","description":"The latest transaction or payment date."},"as_of":{"type":"string","format":"date","title":"As Of","description":"Month-ends are closed and interest accrued through this date."},"spend_cents":{"type":"integer","title":"Spend Cents","description":"Card spend, refunds excluded."},"refunds_cents":{"type":"integer","title":"Refunds Cents","description":"Refunds, as a positive figure."},"repayments_cents":{"type":"integer","title":"Repayments Cents","description":"Repayments."},"merchants":{"items":{"$ref":"#/components/schemas/PartnerExportPlanMerchant"},"type":"array","title":"Merchants","description":"One row per merchant, by external id."},"skipped":{"items":{"type":"string"},"type":"array","title":"Skipped","description":"Why rows were left out, the first 100."},"skipped_total":{"type":"integer","title":"Skipped Total","description":"How many rows were left out.","default":0}},"type":"object","required":["merchant_count","transaction_count","payment_count","as_of","spend_cents","refunds_cents","repayments_cents"],"title":"PartnerExportPlan"},"PartnerExportPlanMerchant":{"properties":{"external_id":{"type":"string","title":"External Id","description":"The merchant's id in the export."},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"The merchant's name, if given."},"credit_limit_cents":{"type":"integer","title":"Credit Limit Cents","description":"The line's credit limit."},"term_days":{"type":"integer","title":"Term Days","description":"The line's repayment term."},"transactions":{"type":"integer","title":"Transactions","description":"Card transactions for this merchant."},"spend_cents":{"type":"integer","title":"Spend Cents","description":"Net card spend (refunds subtracted) for this merchant."},"paid_cents":{"type":"integer","title":"Paid Cents","description":"Repayments for this merchant."}},"type":"object","required":["external_id","credit_limit_cents","term_days","transactions","spend_cents","paid_cents"],"title":"PartnerExportPlanMerchant"},"PartnerExportResponse":{"properties":{"dry_run":{"type":"boolean","title":"Dry Run","description":"True when nothing was written."},"applied":{"type":"boolean","title":"Applied","description":"True when the book was seeded."},"plan":{"$ref":"#/components/schemas/PartnerExportPlan","description":"What the files seed, as figures."},"plan_text":{"type":"string","title":"Plan Text","description":"The same plan as the seeder script prints it."},"mapping_source":{"type":"string","title":"Mapping Source","description":"How the field names were chosen: `defaults`, `given` (the `mapping` sent), or `auto` (worked out from the files).","default":"defaults"},"mapping_notes":{"items":{"type":"string"},"type":"array","title":"Mapping Notes","description":"With `mapping: auto`: each field, the column it was read from, how sure the match is and why, and any field no column answered to."},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings","description":"Values that look like real people's emails or phone numbers, by file, row and attribute (masked). Applying is refused while there are any, unless `allow_unredacted` is sent with a `reason`."},"unredacted_total":{"type":"integer","title":"Unredacted Total","description":"How many un-redacted values were found in all.","default":0},"allow_unredacted":{"type":"boolean","title":"Allow Unredacted","description":"Whether the caller allowed un-redacted data.","default":false},"unredacted_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unredacted Reason","description":"The reason given for allowing it."},"counts":{"anyOf":[{"$ref":"#/components/schemas/PartnerExportCounts"},{"type":"null"}],"description":"What was written, when `applied`."}},"type":"object","required":["dry_run","applied","plan","plan_text"],"title":"PartnerExportResponse"},"SuccessEnvelope_PartnerExportResponse_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"},"data":{"anyOf":[{"$ref":"#/components/schemas/PartnerExportResponse"},{"type":"null"}]}},"additionalProperties":true,"type":"object","title":"SuccessEnvelope[PartnerExportResponse]"},"ErrorResponse":{"title":"ErrorResponse","type":"object","description":"Envelope returned by every non-2xx response. Branch on `code` (stable) rather than `message` (human-readable, may change).","required":["error","message","code"],"properties":{"error":{"type":"string","description":"Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`."},"message":{"type":"string","description":"Human-readable explanation, safe to show to end users."},"code":{"type":"string","description":"Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`)."},"request_id":{"type":"string","description":"Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied."},"errors":{"type":"object","additionalProperties":{"type":"string"},"description":"Field-level validation messages keyed by field name. Present on 400/422 validation failures only."}}}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Token","description":"API token authentication. Format: `Bearer dz_...`"}}},"security":[{"BearerAuth":[]}]}