{"openapi":"3.0.3","info":{"title":"SMSGonder Public API","version":"1.1.0","description":"SMSGonder public OTP API. LIVE uses /api and isolated TEST Sandbox uses /test. The same API Key may be used in both environments; IDs, credits and usage counters are environment-isolated. TEST never calls the live SMS provider. Idempotent retry, exact Hosted return URLs, signed Hosted returns and signed webhooks are part of the integration contract. Controlled LIVE provider failures avoid origin 502/504 so reverse proxies cannot replace the SMSGonder JSON body: PROVIDER_REJECTED uses HTTP 422; PROVIDER_TIMEOUT and PROVIDER_UNAVAILABLE use HTTP 503. API keys identify client applications; Service Modes and approved Templates are independent many-to-many permissions. One key may authorize multiple OTP flows."},"servers":[{"url":"https://www.smsgonder.com.tr","description":"SMSGonder production API host"}],"security":[{"bearerAuth":[]}],"paths":{"/api/send":{"post":{"tags":["LIVE"],"operationId":"liveSend","summary":"Send an OTP message containing a caller-supplied code","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/Send"},"responses":{"200":{"$ref":"#/components/responses/SendAccepted"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}}}},"/api/report":{"post":{"tags":["LIVE"],"operationId":"liveReport","summary":"Read and, when possible, refresh a delivery report","requestBody":{"$ref":"#/components/requestBodies/Report"},"responses":{"200":{"$ref":"#/components/responses/Report"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}},"description":"Provider refresh unavailability is normally represented inside HTTP 200 as provider_report_available=false with report_error. The persisted delivery status remains available."}},"/api/otp/create":{"post":{"tags":["LIVE"],"operationId":"liveOtpCreate","summary":"Generate, send and persist a verification OTP","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/OtpCreate"},"responses":{"200":{"$ref":"#/components/responses/OtpCreated"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}}}},"/api/otp/check":{"post":{"tags":["LIVE"],"operationId":"liveOtpCheck","summary":"Check a verification OTP","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/OtpCheck"},"responses":{"200":{"$ref":"#/components/responses/OtpChecked"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/api/hosted/create":{"post":{"tags":["LIVE"],"operationId":"liveHostedCreate","summary":"Create a mobile Hosted OTP session","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/HostedCreate"},"responses":{"200":{"$ref":"#/components/responses/HostedCreated"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}}}},"/api/balance":{"get":{"tags":["LIVE"],"operationId":"liveBalance","summary":"Read SMS Credit balance and active package","responses":{"200":{"$ref":"#/components/responses/Balance"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/api/usage":{"get":{"tags":["LIVE"],"operationId":"liveUsage","summary":"Read account-aggregate unit and request windows","responses":{"200":{"$ref":"#/components/responses/Usage"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/test/send":{"post":{"tags":["TEST"],"operationId":"testSend","summary":"Sandbox send; never calls a live provider","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/Send"},"responses":{"200":{"$ref":"#/components/responses/SendAccepted"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}},"description":"Sandbox phone 900000000003 returns HTTP 422 PROVIDER_REJECTED JSON; 900000000004 returns HTTP 422 PROVIDER_TIMEOUT JSON."}},"/test/report":{"post":{"tags":["TEST"],"operationId":"testReport","summary":"Sandbox delivery report","requestBody":{"$ref":"#/components/requestBodies/Report"},"responses":{"200":{"$ref":"#/components/responses/Report"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}},"description":"Sandbox delivery report. provider_report_available describes report-source availability; deprecated live is only its alias, not the TEST/LIVE environment flag."}},"/test/otp/create":{"post":{"tags":["TEST"],"operationId":"testOtpCreate","summary":"Sandbox OTP creation; deterministic code is documented for test use","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/OtpCreate"},"responses":{"200":{"$ref":"#/components/responses/OtpCreated"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}},"description":"Sandbox phone 900000000003 returns HTTP 422 PROVIDER_REJECTED JSON; 900000000004 returns HTTP 422 PROVIDER_TIMEOUT JSON."}},"/test/otp/check":{"post":{"tags":["TEST"],"operationId":"testOtpCheck","summary":"Sandbox OTP check","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/OtpCheck"},"responses":{"200":{"$ref":"#/components/responses/OtpChecked"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/test/hosted/create":{"post":{"tags":["TEST"],"operationId":"testHostedCreate","summary":"Create a sandbox Hosted OTP session","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"$ref":"#/components/requestBodies/HostedCreate"},"responses":{"200":{"$ref":"#/components/responses/HostedCreated"},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}},"description":"Sandbox phone 900000000003 returns HTTP 422 PROVIDER_REJECTED JSON; 900000000004 returns HTTP 422 PROVIDER_TIMEOUT JSON."}},"/test/balance":{"get":{"tags":["TEST"],"operationId":"testBalance","summary":"Read virtual TEST credit and TEST package","responses":{"200":{"$ref":"#/components/responses/Balance"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/test/usage":{"get":{"tags":["TEST"],"operationId":"testUsage","summary":"Read TEST unit and request windows","responses":{"200":{"$ref":"#/components/responses/Usage"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"500":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API key"}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Unique key for safe replay. Reusing it with a different body is rejected. Use 8-128 printable ASCII characters. HTTP stacks may normalize optional surrounding whitespace, so clients must not intentionally include it.","schema":{"type":"string","minLength":8,"maxLength":128,"pattern":"^[!-~]+$"},"example":"order-2026-000001"}},"requestBodies":{"Send":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendRequest"},"example":{"phone":"900000000001","template_key":"activation","verification_code":"123456"}}}},"Report":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportRequest"},"example":{"message_id":"msg_replace_from_send"}}}},"OtpCreate":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpCreateRequest"},"example":{"phone":"900000000001","template_key":"activation"}}}},"OtpCheck":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpCheckRequest"},"example":{"otp_id":"otp_replace_from_create","verification_code":"123456"}}}},"HostedCreate":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostedCreateRequest"},"example":{"phone":"900000000001","template_key":"activation","return_url":"https://client.example/otp-return","state":"order-000001"}}}}},"responses":{"SendAccepted":{"description":"One provider attempt accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResponse"},"example":{"success":true,"request_id":"req_example","status":"accepted","message_id":"msg_example"}}}},"OtpCreated":{"description":"OTP created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpCreateResponse"},"example":{"success":true,"request_id":"req_example","status":"accepted","otp_id":"otp_example","message_id":"msg_example","expires_in":300,"max_attempts":5}}}},"OtpChecked":{"description":"OTP state after this attempt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpCheckResponse"},"examples":{"verified":{"value":{"success":true,"request_id":"req_example","otp_id":"otp_example","status":"verified"}},"invalid":{"value":{"success":true,"request_id":"req_example","otp_id":"otp_example","status":"invalid"}}}}}},"HostedCreated":{"description":"Hosted OTP session created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostedCreateResponse"},"example":{"success":true,"request_id":"req_example","status":"accepted","transaction_id":"hotp_example","message_id":"msg_example","hosted_url":"https://www.smsgonder.com.tr/test/otp/token","expires_in":300}}}},"Report":{"description":"Current delivery state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportResponse"},"example":{"success":true,"request_id":"req_example","message_id":"msg_example","status":"delivered","environment":"test","provider_report_available":true,"live":true,"status_updated_at":"2026-09-04T10:00:00Z","checked_at":"2026-09-04T10:00:01Z"}}}},"Balance":{"description":"Current SMS Credit balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BalanceResponse"},"example":{"success":true,"request_id":"req_example","environment":"test","sms_credits":999,"reserved_sms_credits":0,"package":"Test Sandbox"}}}},"Usage":{"description":"Current Turkey-time windows","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"},"example":{"success":true,"request_id":"req_example","environment":"test","package":"Test Sandbox","units":{"second":{"used":0,"limit":20},"minute":{"used":0,"limit":600},"hour":{"used":0,"limit":10000},"day":{"used":0,"limit":100000}},"requests":{"second":{"used":1,"limit":10},"minute":{"used":1,"limit":300},"hour":{"used":1,"limit":5000},"day":{"used":1,"limit":50000}}}}}},"Error":{"description":"Stable public error envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"request_id":"req_example","code":"INVALID_REQUEST","message":"The request is invalid."}}}}},"schemas":{"SendRequest":{"type":"object","additionalProperties":false,"required":["phone","template_key","verification_code"],"properties":{"phone":{"type":"string","pattern":"^[0-9]+$","maxLength":20,"description":"LIVE currently supports Turkish mobile numbers only. Use 905XXXXXXXXX (country code 90, mobile national number starting with 5), digits only; no leading +, domestic leading 0, spaces, dashes or parentheses. TEST Sandbox special numbers 900000000001-900000000005 are deterministic fixtures."},"template_key":{"type":"string","maxLength":80,"description":"Must exactly equal one of the APPROVED TemplateKey values allowed for this API Key."},"verification_code":{"type":"string","minLength":4,"maxLength":8}}},"ReportRequest":{"type":"object","additionalProperties":false,"required":["message_id"],"properties":{"message_id":{"type":"string","maxLength":80}}},"OtpCreateRequest":{"type":"object","additionalProperties":false,"required":["phone","template_key"],"properties":{"phone":{"type":"string","pattern":"^[0-9]+$","maxLength":20,"description":"LIVE currently supports Turkish mobile numbers only. Use 905XXXXXXXXX (country code 90, mobile national number starting with 5), digits only; no leading +, domestic leading 0, spaces, dashes or parentheses. TEST Sandbox special numbers 900000000001-900000000005 are deterministic fixtures."},"template_key":{"type":"string","maxLength":80,"description":"Must exactly equal one of the APPROVED TemplateKey values allowed for this API Key."}}},"OtpCheckRequest":{"type":"object","additionalProperties":false,"required":["otp_id","verification_code"],"properties":{"otp_id":{"type":"string","maxLength":80},"verification_code":{"type":"string","minLength":4,"maxLength":8}}},"HostedCreateRequest":{"type":"object","additionalProperties":false,"required":["phone","template_key","return_url","state"],"properties":{"phone":{"type":"string","pattern":"^[0-9]+$","maxLength":20,"description":"LIVE currently supports Turkish mobile numbers only. Use 905XXXXXXXXX (country code 90, mobile national number starting with 5), digits only; no leading +, domestic leading 0, spaces, dashes or parentheses. TEST Sandbox special numbers 900000000001-900000000005 are deterministic fixtures."},"template_key":{"type":"string","maxLength":80,"description":"Must exactly equal one of the APPROVED TemplateKey values allowed for this API Key."},"return_url":{"type":"string","format":"uri","maxLength":1000,"description":"Exact allowlisted HTTPS URL. Path, query and trailing slash are significant; fragments are not allowed."},"state":{"type":"string","maxLength":256}}},"SendResponse":{"type":"object","required":["success","request_id","status","message_id"],"properties":{"success":{"type":"boolean"},"request_id":{"type":"string"},"status":{"type":"string","enum":["accepted"]},"message_id":{"type":"string"}}},"OtpCreateResponse":{"allOf":[{"$ref":"#/components/schemas/SendResponse"},{"type":"object","required":["otp_id","expires_in","max_attempts"],"properties":{"otp_id":{"type":"string"},"expires_in":{"type":"integer"},"max_attempts":{"type":"integer"}}}]},"OtpCheckResponse":{"type":"object","required":["success","request_id","otp_id","status"],"properties":{"success":{"type":"boolean"},"request_id":{"type":"string"},"otp_id":{"type":"string"},"status":{"type":"string","enum":["verified","invalid","locked","expired"],"description":"HTTP 200 state after the check. invalid means the call succeeded but the code did not match; locked means max attempts reached; expired means TTL elapsed; verified is idempotent on subsequent checks."}},"description":"attempts_remaining is intentionally not part of the current public contract; max_attempts is returned at create time."},"HostedCreateResponse":{"type":"object","required":["success","request_id","status","transaction_id","message_id","hosted_url","expires_in"],"properties":{"success":{"type":"boolean"},"request_id":{"type":"string"},"status":{"type":"string"},"transaction_id":{"type":"string"},"message_id":{"type":"string"},"hosted_url":{"type":"string","format":"uri","description":"Opaque Hosted OTP page URL. TEST uses /test/otp/{token}; LIVE uses /otp/{token}. Active tokens accept GET for the page and POST for the OTP form."},"expires_in":{"type":"integer"}}},"ReportResponse":{"type":"object","required":["success","request_id","message_id","status","environment","provider_report_available","live","checked_at"],"properties":{"success":{"type":"boolean"},"request_id":{"type":"string"},"message_id":{"type":"string"},"status":{"type":"string","enum":["accepted","pending","delivered","failed","unknown"]},"live":{"type":"boolean","deprecated":true,"description":"Deprecated backward-compatible alias of provider_report_available. It is NOT the LIVE/TEST environment flag."},"status_updated_at":{"type":"string","format":"date-time","nullable":true},"checked_at":{"type":"string","format":"date-time"},"report_error":{"type":"object","nullable":true},"environment":{"type":"string","enum":["live","test"],"description":"Actual request environment. Use this field to distinguish LIVE from TEST."},"provider_report_available":{"type":"boolean","description":"Whether the provider/sandbox report source returned a usable report result for this check."}}},"BalanceResponse":{"type":"object","required":["success","request_id","environment","sms_credits","reserved_sms_credits","package"],"properties":{"success":{"type":"boolean"},"request_id":{"type":"string"},"environment":{"type":"string","enum":["live","test"]},"sms_credits":{"type":"integer","format":"int64"},"reserved_sms_credits":{"type":"integer","format":"int64"},"package":{"type":"string"}}},"UsageCounter":{"type":"object","required":["used","limit"],"properties":{"used":{"type":"integer","format":"int64"},"limit":{"type":"integer","format":"int64"}}},"UsageResponse":{"type":"object","required":["success","request_id","environment","package","units","requests"],"properties":{"success":{"type":"boolean"},"request_id":{"type":"string"},"environment":{"type":"string"},"package":{"type":"string"},"units":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/UsageCounter"}},"requests":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/UsageCounter"}}}},"ErrorResponse":{"type":"object","required":["success","request_id","code","message"],"properties":{"success":{"type":"boolean","enum":[false]},"request_id":{"type":"string"},"code":{"type":"string","enum":["INVALID_REQUEST","INVALID_API_KEY","API_KEY_DISABLED","ACCOUNT_SUSPENDED","ACCOUNT_CLOSED","SOURCE_IP_NOT_ALLOWED","SERVICE_MODE_NOT_ALLOWED","INVALID_PHONE","UNSUPPORTED_CALLING_CODE","TEMPLATE_NOT_ALLOWED","TEMPLATE_DISABLED","MESSAGE_TOO_LONG","INSUFFICIENT_SMS_CREDIT","RATE_LIMIT_EXCEEDED","API_UNIT_LIMIT_EXCEEDED","SECURITY_RATE_LIMITED","GATEWAY_NOT_CONFIGURED","REPORT_DISABLED","MESSAGE_NOT_FOUND","OTP_NOT_FOUND","INVALID_RETURN_URL","IDEMPOTENCY_CONFLICT","IDEMPOTENCY_IN_PROGRESS","PROVIDER_REJECTED","PROVIDER_TIMEOUT","PROVIDER_UNAVAILABLE","INTERNAL_ERROR"],"description":"Stable public API error code. OTP verified/invalid/locked/expired are OtpCheckResponse.status values, not error codes."},"message":{"type":"string"}}},"HostedReturnForm":{"type":"object","required":["transaction_id","result","state","timestamp","signature"],"properties":{"transaction_id":{"type":"string"},"result":{"type":"string","enum":["verified","expired","locked"]},"state":{"type":"string","maxLength":256},"timestamp":{"type":"integer","format":"int64","description":"Unix seconds from the first terminal return issuance."},"signature":{"type":"string","description":"Base64 HMAC-SHA256 over transaction_id + newline + result + newline + state + newline + timestamp."}}},"WebhookEvent":{"type":"object","required":["environment","event","event_id","message_id","status","status_updated_at"],"properties":{"environment":{"type":"string","enum":["live","test"]},"event":{"type":"string","example":"sms.delivered"},"event_id":{"type":"string"},"message_id":{"type":"string"},"status":{"type":"string","enum":["accepted","pending","delivered","failed","unknown"]},"status_updated_at":{"type":"string","format":"date-time"}}}}},"x-smsgonder-phone-support":{"live_scope":"Turkish mobile numbers only","calling_code":"90","canonical_format":"905XXXXXXXXX","international_destinations_other_than_turkey":false,"note":"TEST Sandbox numbers 900000000001-900000000005 are deterministic fixtures and are not LIVE destination examples."},"x-smsgonder-sandbox-scenarios":{"900000000001":"send/create accepted; report delivered","900000000002":"send/create accepted; report failed","900000000003":"HTTP 422 PROVIDER_REJECTED JSON; reservation/credit released; idempotent replay","900000000004":"HTTP 422 PROVIDER_TIMEOUT JSON; no real wait; no automatic retry; reservation/credit released; idempotent replay","900000000005":"send accepted; report pending"},"x-smsgonder-service-modes":{"OTP_MESSAGING":["/api/send","/test/send"],"OTP_VERIFICATION":["/api/otp/create","/test/otp/create","/api/otp/check","/test/otp/check"],"HOSTED_OTP":["/api/hosted/create","/test/hosted/create"]},"x-smsgonder-test-limits":{"requests":{"second":10,"minute":300,"hour":5000,"day":50000},"units":{"second":20,"minute":600,"hour":10000,"day":100000},"day_timezone":"Turkey Standard Time"},"x-smsgonder-hosted-return":{"content_type":"application/x-www-form-urlencoded","schema":{"$ref":"#/components/schemas/HostedReturnForm"},"signature_canonical":"transaction_id\\nresult\\nstate\\ntimestamp","signature":"Base64(HMAC-SHA256(UTF8(signing_secret), UTF8(canonical)))","note":"Treat transaction_id idempotently. Repeated delivery of the same signed terminal result is allowed."},"x-smsgonder-webhook":{"content_type":"application/json","schema":{"$ref":"#/components/schemas/WebhookEvent"},"headers":["X-SMSGonder-Event","X-SMSGonder-Event-Id","X-SMSGonder-Timestamp","X-SMSGonder-Signature"],"signature_canonical":"ASCII(timestamp + '.') + raw_body_bytes","signature":"v1=lowerhex(HMAC-SHA256(UTF8(signing_secret), canonical_bytes))","redirects_followed":false},"x-smsgonder-provider-error-transport":{"live_provider_rejected":{"http_status":422,"code":"PROVIDER_REJECTED"},"live_provider_timeout":{"http_status":503,"code":"PROVIDER_TIMEOUT"},"live_provider_unavailable":{"http_status":503,"code":"PROVIDER_UNAVAILABLE"},"reason":"Controlled origin 502/504 responses are avoided because reverse proxies/CDNs may replace their response body. Stable JSON code is authoritative."},"x-smsgonder-api-key-permissions":{"credential":"API Key identifies the client application.","service_modes":["OTP_MESSAGING","OTP_VERIFICATION","HOSTED_OTP"],"service_mode_rule":"Each endpoint requires its own allowed Service Mode. service_mode is not sent in the request body.","templates":"Each API Key may allow one or more APPROVED templates. template_key must exactly match one allowed template.","continuation_exception":"An OTP previously created by a key remains checkable with that same key even if OTP_VERIFICATION permission is later removed."}}