{
	"openapi": "3.0.3",
	"info": {
		"title": "Digital Savings — DJS API",
		"version": "1.0.0",
		"description": "**MoMo Savings+** — a digital locked-savings product for MTN MoMo customers in Congo, operated under the BCH banking licence. This is its DJS (Dynamic Journey Service) API: what MTN's USSD gateway calls, once per step, to drive a customer through a savings journey — registering, depositing into a locked position, checking a balance, withdrawing early, requesting a statement.\n\nEvery operation goes through one of two endpoints, picked by whether it returns a single record or a list; the `operation_name` argument in a shared envelope selects which operation actually runs. Pick an operation from the request/response **examples** below to see the exact envelope to send and the keys you get back.\n\nProduction ingress (the MoMo gateway channel) uses standard TLS (HTTPS) — no client certificate is needed or accepted.\n\nClicking **Try it out** gets you a real response only when this page is loaded from a stage's own docs site (`docs.<stage>-savings-ussd-api.kamoa.io`) with that same stage selected as the server below — any other combination (a different stage's server, or this page loaded from the plain CloudFront domain) is blocked by design, not a bug. To reach any stage from anywhere, use the Postman collection instead."
	},
	"servers": [
		{
			"url": "https://develop-savings-ussd-api.kamoa.io",
			"description": "develop — MoMo sandbox (default), live over HTTPS."
		},
		{
			"url": "https://internal-savings-ussd-api.kamoa.io",
			"description": "internal — our test stage, live over HTTPS."
		}
	],
	"paths": {
		"/getdynamicarguments": {
			"post": {
				"operationId": "getDynamicArguments",
				"summary": "Single-record operations (one record of return keys).",
				"description": "Operations:\n- `check_registration_status` — Is this MSISDN registered? Routes to the Home Menu or to the registration disclosure screen. Returns: registration_status, account_id?, user_email?.\n- `register_savings_account` — Opens the savings account for this MSISDN (idempotent; re-dial → ALREADY_REGISTERED). Returns: registration_result, account_id?, failure_reason?.\n- `create_deposit_summary` — Quotes the chosen amount + lock period against the live offerable product version (no state written). Returns: summary_status, amount?, interest_rate?, estimated_earnings?, total_at_maturity?, duration_days?, minimum_amount?, currency, product_code?, deposit_reference?.\n- `confirm_deposit` — Writes the PENDING PaymentOrder + fires the MoMo Request-to-Pay; PENDING_VALIDATION until the async outcome settles. Trusts the quote create_deposit_summary recorded, not resent amount/product_code. Returns: deposit_status, deposit_reference?, payment_message?, failure_reason?.\n- `create_withdrawal_summary` — Withdrawal preview for one LOCKED position (no state written): what it would pay now vs. what waiting to maturity would earn. Mints withdrawal_reference for confirm. Returns: amount, original_rate, withdrawal_basis, accrued_interest, interest_at_maturity, effective_rate, withdrawable_amount, forfeited_interest, total_payout, currency, settlement_delay, withdrawal_reference.\n- `confirm_withdrawal` — Reserves the LOCKED position + fires the MoMo Disbursement; PENDING until the async outcome settles. Trusts the position create_withdrawal_summary recorded, not a resent locked_account_id. Returns: withdrawal_status, withdrawal_reference?, settlement_reference?, settlement_delay?, failure_reason?.\n- `get_savings_balance` — Savings totals: locked principal + any in-flight withdrawal, with interest earned to date. Paired with list_locked_accounts for the per-position breakdown. Returns: total_balance, total_interest, pending_withdrawal_amount, position_count, currency.\n- `confirm_opt_out` — Early-exits every open locked position, then closes the account once everything has settled. Returns: opt_out_status, failure_reason?, settlement_delay?.\n- `get_user_email` — Fetches the email on file (internal step; happy path = on file). Returns: email, email_status.\n- `create_full_statement_summary` — Mints the reference the confirm step (request_full_statement) echoes back to make it idempotent (no state written). Returns: statement_reference.\n- `request_full_statement` — Confirms/updates the email on file, then hands the period-bounded PDF generation + delivery off to a background worker (async email delivery). Returns: request_status, failure_reason?.",
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"$ref": "#/components/schemas/DjsEnvelope"
							},
							"examples": {
								"check_registration_status": {
									"summary": "Is this MSISDN registered? Routes to the Home Menu or to the registration disclosure screen.",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "check_registration_status"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"register_savings_account": {
									"summary": "Opens the savings account for this MSISDN (idempotent; re-dial → ALREADY_REGISTERED).",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "register_savings_account"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_EMAIL"
												},
												"value": {
													"value": "client@example.cd"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"create_deposit_summary": {
									"summary": "Quotes the chosen amount + lock period against the live offerable product version (no state written).",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "create_deposit_summary"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											},
											{
												"key": {
													"value": "amount"
												},
												"value": {
													"value": "50000"
												}
											},
											{
												"key": {
													"value": "product_code"
												},
												"value": {
													"value": "prod3m"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"confirm_deposit": {
									"summary": "Writes the PENDING PaymentOrder + fires the MoMo Request-to-Pay; PENDING_VALIDATION until the async outcome settles. Trusts the quote create_deposit_summary recorded, not resent amount/product_code.",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "confirm_deposit"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											},
											{
												"key": {
													"value": "deposit_reference"
												},
												"value": {
													"value": "dep_2f1c…"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"create_withdrawal_summary": {
									"summary": "Withdrawal preview for one LOCKED position (no state written): what it would pay now vs. what waiting to maturity would earn. Mints withdrawal_reference for confirm.",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "create_withdrawal_summary"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											},
											{
												"key": {
													"value": "locked_account_id"
												},
												"value": {
													"value": "7ade4636-df3e-4ac9-a73b-32635bccc7d3"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"confirm_withdrawal": {
									"summary": "Reserves the LOCKED position + fires the MoMo Disbursement; PENDING until the async outcome settles. Trusts the position create_withdrawal_summary recorded, not a resent locked_account_id.",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "confirm_withdrawal"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											},
											{
												"key": {
													"value": "withdrawal_reference"
												},
												"value": {
													"value": "c4e7f8a2-1b3d-4f9e-8c0a-5d2e6f7a9b1c"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"get_savings_balance": {
									"summary": "Savings totals: locked principal + any in-flight withdrawal, with interest earned to date. Paired with list_locked_accounts for the per-position breakdown.",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "get_savings_balance"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"confirm_opt_out": {
									"summary": "Early-exits every open locked position, then closes the account once everything has settled.",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "confirm_opt_out"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"get_user_email": {
									"summary": "Fetches the email on file (internal step; happy path = on file).",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "get_user_email"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"create_full_statement_summary": {
									"summary": "Mints the reference the confirm step (request_full_statement) echoes back to make it idempotent (no state written).",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "create_full_statement_summary"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"request_full_statement": {
									"summary": "Confirms/updates the email on file, then hands the period-bounded PDF generation + delivery off to a background worker (async email delivery).",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "request_full_statement"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_EMAIL"
												},
												"value": {
													"value": "client@example.cd"
												}
											},
											{
												"key": {
													"value": "period"
												},
												"value": {
													"value": "3m"
												}
											},
											{
												"key": {
													"value": "statement_reference"
												},
												"value": {
													"value": "stmt_2f1c…"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "The operation's return keys as an arguments record.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ArgumentsResponse"
								},
								"examples": {
									"check_registration_status": {
										"summary": "Is this MSISDN registered? Routes to the Home Menu or to the registration disclosure screen.",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "registration_status"
													},
													"value": {
														"value": "REGISTERED"
													}
												},
												{
													"key": {
														"value": "account_id"
													},
													"value": {
														"value": "7ade4636-df3e-4ac9-a73b-32635bccc7d3"
													}
												},
												{
													"key": {
														"value": "user_email"
													},
													"value": {
														"value": "client@example.cd"
													}
												}
											]
										}
									},
									"register_savings_account": {
										"summary": "Opens the savings account for this MSISDN (idempotent; re-dial → ALREADY_REGISTERED).",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "registration_result"
													},
													"value": {
														"value": "REGISTERED"
													}
												},
												{
													"key": {
														"value": "account_id"
													},
													"value": {
														"value": "7ade4636-df3e-4ac9-a73b-32635bccc7d3"
													}
												}
											]
										}
									},
									"create_deposit_summary": {
										"summary": "Quotes the chosen amount + lock period against the live offerable product version (no state written).",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "summary_status"
													},
													"value": {
														"value": "OK"
													}
												},
												{
													"key": {
														"value": "amount"
													},
													"value": {
														"value": "50000"
													}
												},
												{
													"key": {
														"value": "interest_rate"
													},
													"value": {
														"value": "5"
													}
												},
												{
													"key": {
														"value": "estimated_earnings"
													},
													"value": {
														"value": "625"
													}
												},
												{
													"key": {
														"value": "total_at_maturity"
													},
													"value": {
														"value": "50625"
													}
												},
												{
													"key": {
														"value": "duration_days"
													},
													"value": {
														"value": "91"
													}
												},
												{
													"key": {
														"value": "currency"
													},
													"value": {
														"value": "XAF"
													}
												},
												{
													"key": {
														"value": "product_code"
													},
													"value": {
														"value": "prod3m"
													}
												},
												{
													"key": {
														"value": "deposit_reference"
													},
													"value": {
														"value": "dep_2f1c…"
													}
												}
											]
										}
									},
									"confirm_deposit": {
										"summary": "Writes the PENDING PaymentOrder + fires the MoMo Request-to-Pay; PENDING_VALIDATION until the async outcome settles. Trusts the quote create_deposit_summary recorded, not resent amount/product_code.",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "deposit_status"
													},
													"value": {
														"value": "PENDING_VALIDATION"
													}
												},
												{
													"key": {
														"value": "deposit_reference"
													},
													"value": {
														"value": "dep_2f1c…"
													}
												},
												{
													"key": {
														"value": "payment_message"
													},
													"value": {
														"value": "Confirmez le paiement sur votre téléphone MoMo (saisissez votre code PIN)."
													}
												}
											]
										}
									},
									"create_withdrawal_summary": {
										"summary": "Withdrawal preview for one LOCKED position (no state written): what it would pay now vs. what waiting to maturity would earn. Mints withdrawal_reference for confirm.",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "amount"
													},
													"value": {
														"value": "100000"
													}
												},
												{
													"key": {
														"value": "original_rate"
													},
													"value": {
														"value": "5"
													}
												},
												{
													"key": {
														"value": "withdrawal_basis"
													},
													"value": {
														"value": "EARLY_EXIT"
													}
												},
												{
													"key": {
														"value": "accrued_interest"
													},
													"value": {
														"value": "833"
													}
												},
												{
													"key": {
														"value": "interest_at_maturity"
													},
													"value": {
														"value": "1250"
													}
												},
												{
													"key": {
														"value": "effective_rate"
													},
													"value": {
														"value": "4.5"
													}
												},
												{
													"key": {
														"value": "withdrawable_amount"
													},
													"value": {
														"value": "750"
													}
												},
												{
													"key": {
														"value": "forfeited_interest"
													},
													"value": {
														"value": "83"
													}
												},
												{
													"key": {
														"value": "total_payout"
													},
													"value": {
														"value": "100750"
													}
												},
												{
													"key": {
														"value": "currency"
													},
													"value": {
														"value": "XAF"
													}
												},
												{
													"key": {
														"value": "settlement_delay"
													},
													"value": {
														"value": "48h"
													}
												},
												{
													"key": {
														"value": "withdrawal_reference"
													},
													"value": {
														"value": "c4e7f8a2-1b3d-4f9e-8c0a-5d2e6f7a9b1c"
													}
												}
											]
										}
									},
									"confirm_withdrawal": {
										"summary": "Reserves the LOCKED position + fires the MoMo Disbursement; PENDING until the async outcome settles. Trusts the position create_withdrawal_summary recorded, not a resent locked_account_id.",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "withdrawal_status"
													},
													"value": {
														"value": "PENDING"
													}
												},
												{
													"key": {
														"value": "withdrawal_reference"
													},
													"value": {
														"value": "c4e7f8a2-1b3d-4f9e-8c0a-5d2e6f7a9b1c"
													}
												},
												{
													"key": {
														"value": "settlement_delay"
													},
													"value": {
														"value": "48h"
													}
												}
											]
										}
									},
									"get_savings_balance": {
										"summary": "Savings totals: locked principal + any in-flight withdrawal, with interest earned to date. Paired with list_locked_accounts for the per-position breakdown.",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "total_balance"
													},
													"value": {
														"value": "120000"
													}
												},
												{
													"key": {
														"value": "total_interest"
													},
													"value": {
														"value": "932"
													}
												},
												{
													"key": {
														"value": "pending_withdrawal_amount"
													},
													"value": {
														"value": "0"
													}
												},
												{
													"key": {
														"value": "position_count"
													},
													"value": {
														"value": "2"
													}
												},
												{
													"key": {
														"value": "currency"
													},
													"value": {
														"value": "XAF"
													}
												}
											]
										}
									},
									"confirm_opt_out": {
										"summary": "Early-exits every open locked position, then closes the account once everything has settled.",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "opt_out_status"
													},
													"value": {
														"value": "COMPLETED"
													}
												},
												{
													"key": {
														"value": "settlement_delay"
													},
													"value": {
														"value": "48h"
													}
												}
											]
										}
									},
									"get_user_email": {
										"summary": "Fetches the email on file (internal step; happy path = on file).",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "email"
													},
													"value": {
														"value": "client@example.cd"
													}
												},
												{
													"key": {
														"value": "email_status"
													},
													"value": {
														"value": "ON_FILE"
													}
												}
											]
										}
									},
									"create_full_statement_summary": {
										"summary": "Mints the reference the confirm step (request_full_statement) echoes back to make it idempotent (no state written).",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "statement_reference"
													},
													"value": {
														"value": "stmt_2f1c…"
													}
												}
											]
										}
									},
									"request_full_statement": {
										"summary": "Confirms/updates the email on file, then hands the period-bounded PDF generation + delivery off to a background worker (async email delivery).",
										"value": {
											"arguments": [
												{
													"key": {
														"value": "request_status"
													},
													"value": {
														"value": "REQUESTED"
													}
												}
											]
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Malformed envelope, invalid JSON, or unknown operation.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					}
				}
			}
		},
		"/getdynamicoptions": {
			"post": {
				"operationId": "getDynamicOptions",
				"summary": "Collection operations (one row of keys per option).",
				"description": "Operations:\n- `list_locked_accounts` — Locked positions the customer can withdraw from — also backs the balance screen's per-position breakdown (get_savings_balance only carries totals). One row per open LOCKED position; balance reflects any in-progress reservation. Returns: locked_account_id, label, maturity_date, current_balance, locked_rate, accrued_interest, interest_at_maturity, withdrawable_amount, withdrawal_basis.\n- `list_opt_out_positions` — The closure breakdown: every open locked position with its early-exit terms, so the pre-confirmation screen can show what confirm_opt_out would settle. Returns: locked_account_id, label, maturity_date, current_balance, withdrawal_basis, original_rate, effective_rate, accrued_interest, forfeited_interest, payout, currency, total_payout, settlement_delay.\n- `list_recent_transactions` — The last few transactions (mini statement). Returns: transaction_id, transaction_date, transaction_type, transaction_status, amount, currency.",
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"$ref": "#/components/schemas/DjsEnvelope"
							},
							"examples": {
								"list_locked_accounts": {
									"summary": "Locked positions the customer can withdraw from — also backs the balance screen's per-position breakdown (get_savings_balance only carries totals). One row per open LOCKED position; balance reflects any in-progress reservation.",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "list_locked_accounts"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"list_opt_out_positions": {
									"summary": "The closure breakdown: every open locked position with its early-exit terms, so the pre-confirmation screen can show what confirm_opt_out would settle.",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "list_opt_out_positions"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								},
								"list_recent_transactions": {
									"summary": "The last few transactions (mini statement).",
									"value": {
										"arguments": [
											{
												"key": {
													"value": "operation_name"
												},
												"value": {
													"value": "list_recent_transactions"
												}
											},
											{
												"key": {
													"value": "ACCOUNT_HOLDER_MSISDN"
												},
												"value": {
													"value": "242060000001"
												}
											}
										],
										"languageCode": "fr",
										"sessionIdentifier": "example-session",
										"journeyIdentifier": "example-journey"
									}
								}
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "The options as an argumentsList (one row of keys each).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ArgumentsListResponse"
								},
								"examples": {
									"list_locked_accounts": {
										"summary": "Locked positions the customer can withdraw from — also backs the balance screen's per-position breakdown (get_savings_balance only carries totals). One row per open LOCKED position; balance reflects any in-progress reservation.",
										"value": {
											"argumentsList": [
												[
													{
														"key": {
															"value": "locked_account_id"
														},
														"value": {
															"value": "7ade4636-df3e-4ac9-a73b-32635bccc7d3"
														}
													},
													{
														"key": {
															"value": "label"
														},
														"value": {
															"value": "3 mois - 50000 FCFA"
														}
													},
													{
														"key": {
															"value": "maturity_date"
														},
														"value": {
															"value": "2026-09-11"
														}
													},
													{
														"key": {
															"value": "current_balance"
														},
														"value": {
															"value": "50000"
														}
													},
													{
														"key": {
															"value": "locked_rate"
														},
														"value": {
															"value": "5.5"
														}
													},
													{
														"key": {
															"value": "accrued_interest"
														},
														"value": {
															"value": "458"
														}
													},
													{
														"key": {
															"value": "interest_at_maturity"
														},
														"value": {
															"value": "687"
														}
													},
													{
														"key": {
															"value": "withdrawable_amount"
														},
														"value": {
															"value": "412"
														}
													},
													{
														"key": {
															"value": "withdrawal_basis"
														},
														"value": {
															"value": "EARLY_EXIT"
														}
													}
												]
											]
										}
									},
									"list_opt_out_positions": {
										"summary": "The closure breakdown: every open locked position with its early-exit terms, so the pre-confirmation screen can show what confirm_opt_out would settle.",
										"value": {
											"argumentsList": [
												[
													{
														"key": {
															"value": "locked_account_id"
														},
														"value": {
															"value": "7ade4636-df3e-4ac9-a73b-32635bccc7d3"
														}
													},
													{
														"key": {
															"value": "label"
														},
														"value": {
															"value": "3 mois - 50000 FCFA"
														}
													},
													{
														"key": {
															"value": "maturity_date"
														},
														"value": {
															"value": "2026-09-11"
														}
													},
													{
														"key": {
															"value": "current_balance"
														},
														"value": {
															"value": "50000"
														}
													},
													{
														"key": {
															"value": "withdrawal_basis"
														},
														"value": {
															"value": "EARLY_EXIT"
														}
													},
													{
														"key": {
															"value": "original_rate"
														},
														"value": {
															"value": "5.5"
														}
													},
													{
														"key": {
															"value": "effective_rate"
														},
														"value": {
															"value": "3.2"
														}
													},
													{
														"key": {
															"value": "accrued_interest"
														},
														"value": {
															"value": "458"
														}
													},
													{
														"key": {
															"value": "forfeited_interest"
														},
														"value": {
															"value": "46"
														}
													},
													{
														"key": {
															"value": "payout"
														},
														"value": {
															"value": "50412"
														}
													},
													{
														"key": {
															"value": "currency"
														},
														"value": {
															"value": "XAF"
														}
													},
													{
														"key": {
															"value": "total_payout"
														},
														"value": {
															"value": "50412"
														}
													},
													{
														"key": {
															"value": "settlement_delay"
														},
														"value": {
															"value": "48h"
														}
													}
												]
											]
										}
									},
									"list_recent_transactions": {
										"summary": "The last few transactions (mini statement).",
										"value": {
											"argumentsList": [
												[
													{
														"key": {
															"value": "transaction_id"
														},
														"value": {
															"value": "7ade4636-df3e-4ac9-a73b-32635bccc7d3"
														}
													},
													{
														"key": {
															"value": "transaction_date"
														},
														"value": {
															"value": "2026-06-10"
														}
													},
													{
														"key": {
															"value": "transaction_type"
														},
														"value": {
															"value": "DEPOSIT"
														}
													},
													{
														"key": {
															"value": "transaction_status"
														},
														"value": {
															"value": "SETTLED"
														}
													},
													{
														"key": {
															"value": "amount"
														},
														"value": {
															"value": "50000"
														}
													},
													{
														"key": {
															"value": "currency"
														},
														"value": {
															"value": "XAF"
														}
													}
												],
												[
													{
														"key": {
															"value": "transaction_id"
														},
														"value": {
															"value": "a1f2e3d4-5b6c-7d8e-9f01-234567890abc"
														}
													},
													{
														"key": {
															"value": "transaction_date"
														},
														"value": {
															"value": "2026-06-09"
														}
													},
													{
														"key": {
															"value": "transaction_type"
														},
														"value": {
															"value": "MATURITY"
														}
													},
													{
														"key": {
															"value": "transaction_status"
														},
														"value": {
															"value": "PENDING"
														}
													},
													{
														"key": {
															"value": "amount"
														},
														"value": {
															"value": "125"
														}
													},
													{
														"key": {
															"value": "currency"
														},
														"value": {
															"value": "XAF"
														}
													}
												]
											]
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Malformed envelope, invalid JSON, or unknown operation.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/ErrorResponse"
								}
							}
						}
					}
				}
			}
		}
	},
	"components": {
		"schemas": {
			"ArgPair": {
				"type": "object",
				"properties": {
					"key": {
						"type": "object",
						"properties": {
							"value": {
								"type": "string"
							}
						},
						"required": [
							"value"
						]
					},
					"value": {
						"type": "object",
						"properties": {
							"value": {
								"type": "string"
							}
						},
						"required": [
							"value"
						]
					}
				},
				"required": [
					"key",
					"value"
				]
			},
			"DjsEnvelope": {
				"type": "object",
				"description": "The DJS envelope: a flat list of key/value pairs plus session metadata. `operation_name` selects the operation.",
				"properties": {
					"arguments": {
						"type": "array",
						"items": {
							"$ref": "#/components/schemas/ArgPair"
						}
					},
					"languageCode": {
						"type": "string",
						"default": "fr"
					},
					"sessionIdentifier": {
						"type": "string"
					},
					"journeyIdentifier": {
						"type": "string"
					}
				},
				"required": [
					"arguments",
					"sessionIdentifier",
					"journeyIdentifier"
				]
			},
			"ArgumentsResponse": {
				"type": "object",
				"properties": {
					"arguments": {
						"type": "array",
						"items": {
							"$ref": "#/components/schemas/ArgPair"
						}
					}
				},
				"required": [
					"arguments"
				]
			},
			"ArgumentsListResponse": {
				"type": "object",
				"properties": {
					"argumentsList": {
						"type": "array",
						"items": {
							"type": "array",
							"items": {
								"$ref": "#/components/schemas/ArgPair"
							}
						}
					}
				},
				"required": [
					"argumentsList"
				]
			},
			"ErrorResponse": {
				"type": "object",
				"properties": {
					"error": {
						"type": "object",
						"properties": {
							"code": {
								"type": "string"
							},
							"message": {
								"type": "string"
							}
						},
						"required": [
							"code",
							"message"
						]
					}
				},
				"required": [
					"error"
				]
			},
			"CheckRegistrationStatusOutput": {
				"type": "object",
				"properties": {
					"registration_status": {
						"type": "string",
						"description": "Whether the MSISDN already has an account.",
						"enum": [
							"REGISTERED",
							"NOT_REGISTERED"
						]
					},
					"account_id": {
						"type": "string",
						"description": "Opaque account reference; present when REGISTERED."
					},
					"user_email": {
						"type": "string",
						"description": "Email on file; present when REGISTERED and one was supplied."
					}
				},
				"required": [
					"registration_status"
				],
				"additionalProperties": false
			},
			"RegisterSavingsAccountOutput": {
				"type": "object",
				"properties": {
					"registration_result": {
						"type": "string",
						"description": "Outcome of the open-account attempt.",
						"enum": [
							"REGISTERED",
							"ALREADY_REGISTERED",
							"FAILED"
						]
					},
					"account_id": {
						"type": "string",
						"description": "Opaque account reference; present on REGISTERED/ALREADY_REGISTERED."
					},
					"failure_reason": {
						"type": "string",
						"description": "Generic reason; present only on FAILED (identity not yet resolvable, or resolver unavailable — try again)."
					}
				},
				"required": [
					"registration_result"
				],
				"additionalProperties": false
			},
			"CreateDepositSummaryOutput": {
				"type": "object",
				"properties": {
					"summary_status": {
						"type": "string",
						"description": "OK | AMOUNT_TOO_LOW."
					},
					"amount": {
						"type": "string",
						"description": "Deposit amount (XAF)."
					},
					"interest_rate": {
						"type": "string",
						"description": "Annual rate, bare percent (e.g. 5)."
					},
					"estimated_earnings": {
						"type": "string",
						"description": "Projected interest at maturity (XAF)."
					},
					"total_at_maturity": {
						"type": "string",
						"description": "Principal + projected interest (XAF)."
					},
					"duration_days": {
						"type": "string",
						"description": "Lock term in days."
					},
					"minimum_amount": {
						"type": "string",
						"description": "Product minimum (present when AMOUNT_TOO_LOW)."
					},
					"currency": {
						"type": "string",
						"description": "ISO currency (XAF)."
					},
					"product_code": {
						"type": "string",
						"description": "Echoed for confirm."
					},
					"deposit_reference": {
						"type": "string",
						"description": "Minted X-Reference-Id, carried into confirm."
					}
				},
				"required": [
					"summary_status",
					"currency"
				],
				"additionalProperties": false
			},
			"ConfirmDepositOutput": {
				"type": "object",
				"properties": {
					"deposit_status": {
						"type": "string",
						"description": "PENDING_VALIDATION | FAILED."
					},
					"deposit_reference": {
						"type": "string",
						"description": "The deposit reference (PENDING_VALIDATION)."
					},
					"payment_message": {
						"type": "string",
						"description": "Customer-facing PIN prompt (PENDING_VALIDATION)."
					},
					"failure_reason": {
						"type": "string",
						"description": "Why the deposit couldn't start (FAILED)."
					}
				},
				"required": [
					"deposit_status"
				],
				"additionalProperties": false
			},
			"CreateWithdrawalSummaryOutput": {
				"type": "object",
				"properties": {
					"amount": {
						"type": "string",
						"description": "Principal being withdrawn (XAF)."
					},
					"original_rate": {
						"type": "string",
						"description": "The rate this position locked in at, bare percent (e.g. 5)."
					},
					"withdrawal_basis": {
						"type": "string",
						"description": "EARLY_EXIT (before maturity, discount applies) or AT_MATURITY (on/after maturity, full rate) — which figures below reflect."
					},
					"accrued_interest": {
						"type": "string",
						"description": "Interest earned so far at the full locked rate — not discounted, not what confirming now pays out (XAF)."
					},
					"interest_at_maturity": {
						"type": "string",
						"description": "Interest this position would earn if left to run to full term instead — the tradeoff against withdrawing now (XAF)."
					},
					"effective_rate": {
						"type": "string",
						"description": "The rate withdrawable_amount was actually computed at — discounted under EARLY_EXIT, equal to original_rate under AT_MATURITY. Bare percent."
					},
					"withdrawable_amount": {
						"type": "string",
						"description": "Interest actually paid if this quote is confirmed now (XAF)."
					},
					"forfeited_interest": {
						"type": "string",
						"description": "accrued_interest minus withdrawable_amount — interest given up by not waiting. Zero under AT_MATURITY (XAF)."
					},
					"total_payout": {
						"type": "string",
						"description": "amount + withdrawable_amount — the full disbursement if confirmed (XAF)."
					},
					"currency": {
						"type": "string",
						"description": "ISO currency (XAF)."
					},
					"settlement_delay": {
						"type": "string",
						"description": "Expected disbursement delay (e.g. 48h under EARLY_EXIT; 'immediate' under AT_MATURITY — the maturity fast path fires with no hold)."
					},
					"withdrawal_reference": {
						"type": "string",
						"description": "Minted X-Reference-Id, carried into confirmWithdrawal."
					}
				},
				"required": [
					"amount",
					"original_rate",
					"withdrawal_basis",
					"accrued_interest",
					"interest_at_maturity",
					"effective_rate",
					"withdrawable_amount",
					"forfeited_interest",
					"total_payout",
					"currency",
					"settlement_delay",
					"withdrawal_reference"
				],
				"additionalProperties": false
			},
			"ConfirmWithdrawalOutput": {
				"type": "object",
				"properties": {
					"withdrawal_status": {
						"type": "string",
						"description": "PENDING | FAILED."
					},
					"withdrawal_reference": {
						"type": "string",
						"description": "The withdrawal reference (PENDING)."
					},
					"settlement_reference": {
						"type": "string",
						"description": "The maturity fast path's own PaymentOrder reference — present only for an on-time exit (past the position's maturityDate). Statements display transactions under this reference, not withdrawal_reference, so a client polling for the outcome should store this one."
					},
					"settlement_delay": {
						"type": "string",
						"description": "Time remaining until disbursement (e.g. 48h), present on PENDING while a hold is still in flight. Absent once the order has already settled — nothing left to wait on."
					},
					"failure_reason": {
						"type": "string",
						"description": "Why the withdrawal couldn't start (FAILED)."
					}
				},
				"required": [
					"withdrawal_status"
				],
				"additionalProperties": false
			},
			"GetSavingsBalanceOutput": {
				"type": "object",
				"properties": {
					"total_balance": {
						"type": "string",
						"description": "Total locked principal across all open positions, plus pending_withdrawal_amount (whole XAF)."
					},
					"total_interest": {
						"type": "string",
						"description": "Total interest earned to date across open positions (whole XAF)."
					},
					"pending_withdrawal_amount": {
						"type": "string",
						"description": "Money reserved out of a position for an in-flight withdrawal, not yet disbursed or reversed — still the customer's, just mid-transfer. Zero outside an active hold (whole XAF)."
					},
					"position_count": {
						"type": "string",
						"description": "How many open positions make up total_balance. list_locked_accounts lists which ones, each with its own rate and interest."
					},
					"currency": {
						"type": "string",
						"description": "ISO currency (FCFA)."
					}
				},
				"required": [
					"total_balance",
					"total_interest",
					"pending_withdrawal_amount",
					"position_count",
					"currency"
				],
				"additionalProperties": false
			},
			"ConfirmOptOutOutput": {
				"type": "object",
				"properties": {
					"opt_out_status": {
						"type": "string",
						"description": "COMPLETED | PENDING | FAILED."
					},
					"failure_reason": {
						"type": "string",
						"description": "Why closure couldn't complete (FAILED)."
					},
					"settlement_delay": {
						"type": "string",
						"description": "Worst-case delay before every closed position's funds have landed (COMPLETED only) — the longest remaining hold across the batch. Absent once nothing in the batch is still on a hold."
					}
				},
				"required": [
					"opt_out_status"
				],
				"additionalProperties": false
			},
			"GetUserEmailOutput": {
				"type": "object",
				"properties": {
					"email": {
						"type": "string",
						"description": "Email on file."
					},
					"email_status": {
						"type": "string",
						"description": "ON_FILE or NOT_ON_FILE."
					}
				},
				"required": [
					"email",
					"email_status"
				],
				"additionalProperties": false
			},
			"CreateFullStatementSummaryOutput": {
				"type": "object",
				"properties": {
					"statement_reference": {
						"type": "string",
						"description": "Minted reference, carried into request_full_statement."
					}
				},
				"required": [
					"statement_reference"
				],
				"additionalProperties": false
			},
			"RequestFullStatementOutput": {
				"type": "object",
				"properties": {
					"request_status": {
						"type": "string",
						"description": "REQUESTED | FAILED."
					},
					"failure_reason": {
						"type": "string",
						"description": "Generic reason; present only on FAILED."
					}
				},
				"required": [
					"request_status"
				],
				"additionalProperties": false
			},
			"ListLockedAccountsOutput": {
				"type": "object",
				"properties": {
					"locked_account_id": {
						"type": "string",
						"description": "Locked-position reference."
					},
					"label": {
						"type": "string",
						"description": "Human label shown on the USSD menu (duration + balance, e.g. '3 mois - 50000 FCFA')."
					},
					"maturity_date": {
						"type": "string",
						"description": "ISO-8601 maturity date."
					},
					"current_balance": {
						"type": "string",
						"description": "Current principal balance of the position (whole XAF)."
					},
					"locked_rate": {
						"type": "string",
						"description": "Annual rate this position locked in at, bare percent (e.g. 5.5)."
					},
					"accrued_interest": {
						"type": "string",
						"description": "Interest earned so far at the full locked rate — not discounted, not what an early exit would pay out (whole XAF)."
					},
					"interest_at_maturity": {
						"type": "string",
						"description": "Interest this position will have earned if left to run to its own maturity_date (whole XAF)."
					},
					"withdrawable_amount": {
						"type": "string",
						"description": "What a withdrawal today would actually pay — see withdrawal_basis for which figure this is (whole XAF)."
					},
					"withdrawal_basis": {
						"type": "string",
						"description": "EARLY_EXIT (discount applied, before maturity_date) or AT_MATURITY (full rate, on/after maturity_date) — which one withdrawable_amount reflects."
					}
				},
				"required": [
					"locked_account_id",
					"label",
					"maturity_date",
					"current_balance",
					"locked_rate",
					"accrued_interest",
					"interest_at_maturity",
					"withdrawable_amount",
					"withdrawal_basis"
				],
				"additionalProperties": false
			},
			"ListOptOutPositionsOutput": {
				"type": "object",
				"properties": {
					"locked_account_id": {
						"type": "string",
						"description": "Locked-position reference."
					},
					"label": {
						"type": "string",
						"description": "Human label shown on the USSD menu (duration + balance, e.g. '3 mois - 50000 FCFA')."
					},
					"maturity_date": {
						"type": "string",
						"description": "ISO-8601 maturity date."
					},
					"current_balance": {
						"type": "string",
						"description": "Current principal balance of the position (whole XAF)."
					},
					"withdrawal_basis": {
						"type": "string",
						"description": "EARLY_EXIT (discount applied, before maturity_date) or AT_MATURITY (full rate, on/after maturity_date) — which one this position's payout reflects."
					},
					"original_rate": {
						"type": "string",
						"description": "Annual rate this position locked in at, bare percent (e.g. 5.5)."
					},
					"effective_rate": {
						"type": "string",
						"description": "Rate actually applied to this payout — discounted under EARLY_EXIT, same as original_rate under AT_MATURITY."
					},
					"accrued_interest": {
						"type": "string",
						"description": "Interest earned so far at the full locked rate — not discounted (whole XAF)."
					},
					"forfeited_interest": {
						"type": "string",
						"description": "Interest given up by closing now instead of at maturity — zero under AT_MATURITY (whole XAF)."
					},
					"payout": {
						"type": "string",
						"description": "What this position pays out: current_balance plus its own withdrawable interest (whole XAF)."
					},
					"currency": {
						"type": "string",
						"description": "ISO currency (XAF)."
					},
					"total_payout": {
						"type": "string",
						"description": "Sum of payout across every open position in this closure — repeated on every row (no separate top-level field on a collection op)."
					},
					"settlement_delay": {
						"type": "string",
						"description": "This position's own delay before disbursement — 'immediate' for an already-matured position, the configured early-exit hold otherwise (e.g. 48h)."
					}
				},
				"required": [
					"locked_account_id",
					"label",
					"maturity_date",
					"current_balance",
					"withdrawal_basis",
					"original_rate",
					"effective_rate",
					"accrued_interest",
					"forfeited_interest",
					"payout",
					"currency",
					"total_payout",
					"settlement_delay"
				],
				"additionalProperties": false
			},
			"ListRecentTransactionsOutput": {
				"type": "object",
				"properties": {
					"transaction_id": {
						"type": "string",
						"description": "The payment provider's own transaction reference where available, else our internal reference. Never blank."
					},
					"transaction_date": {
						"type": "string",
						"description": "ISO-8601 transaction date."
					},
					"transaction_type": {
						"type": "string",
						"description": "DEPOSIT, MATURITY, EARLY_EXIT, REVERSAL, or FUNDING."
					},
					"transaction_status": {
						"type": "string",
						"description": "PENDING, SETTLED, or FAILED — whether the transaction has actually completed."
					},
					"amount": {
						"type": "string",
						"description": "Transaction amount."
					},
					"currency": {
						"type": "string",
						"description": "ISO currency (FCFA)."
					}
				},
				"required": [
					"transaction_id",
					"transaction_date",
					"transaction_type",
					"transaction_status",
					"amount",
					"currency"
				],
				"additionalProperties": false
			}
		}
	}
}
