{"openapi":"3.1.0","info":{"title":"POST /api/v1/subscriptions/create-templates","version":"1.0.0","description":"Create recurring bill templates from detected patterns"},"servers":[{"url":"https://api.ondayzero.com","description":"Production"}],"paths":{"/api/v1/subscriptions/create-templates":{"post":{"tags":["subscriptions"],"summary":"Create recurring bill templates from detected patterns","description":"Turn detected recurring spend into recurring bill templates in one call: name the rows (`counterparty_keys`, as listed by `GET /`) or take every row at or above `min_confidence`. Vendor, amount, cadence and first date come from the detection (re-run server-side). A row with no vendor of that name, a semi-annual row, or a vendor that already has an open template on that cadence is skipped with a reason; each row is isolated. `dry_run` plans without creating.","operationId":"create_templates_from_detection","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":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplatesFromDetectionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope_CreateTemplatesFromDetectionResponse_"}}}},"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"}}}},"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":"create_templates_from_detection_api_v1_subscriptions_create_templates_post"}}},"components":{"schemas":{"CreateTemplatesFromDetectionRequest":{"properties":{"counterparty_keys":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":100},{"type":"null"}],"title":"Counterparty Keys","description":"counterparty_key of the detected rows to turn into templates. Omit to use min_confidence."},"min_confidence":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Min Confidence","description":"Every detected row at or above this confidence (keys omitted)."},"lookback_days":{"type":"integer","maximum":730.0,"minimum":30.0,"title":"Lookback Days","description":"Detection window; match the list you showed.","default":180},"vendor_overrides":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Vendor Overrides","description":"counterparty_key -> vendor_id for rows whose vendor is not found by name."},"dry_run":{"type":"boolean","title":"Dry Run","description":"Plan the templates; create nothing.","default":false},"plan_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Hash","description":"plan_hash of the dry run; refused if the patterns moved"}},"type":"object","title":"CreateTemplatesFromDetectionRequest","description":"Create recurring bill templates from detected recurring spend."},"CreateTemplatesFromDetectionResponse":{"properties":{"dry_run":{"type":"boolean","title":"Dry Run","default":false},"created":{"type":"integer","title":"Created","default":0},"would_create":{"type":"integer","title":"Would Create","default":0},"skipped":{"type":"integer","title":"Skipped","default":0},"failed":{"type":"integer","title":"Failed","default":0},"not_detected":{"items":{"type":"string"},"type":"array","title":"Not Detected"},"truncated":{"type":"boolean","title":"Truncated","default":false},"plan_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan Hash","description":"Digest of the dry-run plan; pass it to apply"},"results":{"items":{"$ref":"#/components/schemas/TemplateFromDetectionRow"},"type":"array","title":"Results"}},"type":"object","title":"CreateTemplatesFromDetectionResponse"},"SuccessEnvelope_CreateTemplatesFromDetectionResponse_":{"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/CreateTemplatesFromDetectionResponse"},{"type":"null"}]}},"additionalProperties":true,"type":"object","title":"SuccessEnvelope[CreateTemplatesFromDetectionResponse]"},"TemplateFromDetectionRow":{"properties":{"counterparty_key":{"type":"string","title":"Counterparty Key"},"name":{"type":"string","title":"Name"},"status":{"type":"string","title":"Status","description":"created | would_create | skipped | failed"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"needs_vendor | unsupported_frequency | already_templated | vendor_not_found | create_failed"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"template_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Id"},"vendor_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vendor Id"},"amount_cents":{"type":"integer","title":"Amount Cents","default":0},"frequency":{"type":"string","title":"Frequency"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"},"start_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Date"}},"type":"object","required":["counterparty_key","name","status","frequency"],"title":"TemplateFromDetectionRow","description":"One detected pattern a create call planned or tried."},"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":[]}]}