{
  "info": {
    "name": "otpmagiclink API",
    "_postman_id": "otpmagiclink-api-v1",
    "description": "OTP and magic-link verification API.\n\n## Setup\n1. Import this collection into Postman.\n2. Open **Variables** and set `baseUrl` and `apiKey`.\n3. Run **Create verification (OTP email)** — `verificationId` is saved automatically.\n4. Use **Check OTP** with `otpToken` from sandbox inbox or your email.\n\nSandbox projects capture messages instead of sending real email/SMS.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{apiKey}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "http://localhost:7000",
      "type": "string"
    },
    {
      "key": "apiKey",
      "value": "sk_your_api_key_here",
      "type": "string"
    },
    {
      "key": "identifier",
      "value": "user@example.com",
      "type": "string"
    },
    {
      "key": "verificationId",
      "value": "",
      "type": "string"
    },
    {
      "key": "otpToken",
      "value": "482910",
      "type": "string"
    },
    {
      "key": "redirectUrl",
      "value": "https://yourapp.com/dashboard",
      "type": "string"
    },
    {
      "key": "sandboxClockSeconds",
      "value": "600",
      "type": "string"
    },
    {
      "key": "inboxLimit",
      "value": "20",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "Verifications",
      "item": [
        {
          "name": "Create verification (OTP email)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 201) {",
                  "  const json = pm.response.json();",
                  "  if (json.id) {",
                  "    pm.collectionVariables.set('verificationId', json.id);",
                  "    console.log('Saved verificationId:', json.id);",
                  "  }",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"identifier\": \"{{identifier}}\",\n  \"channel\": \"EMAIL\",\n  \"kind\": \"OTP\"\n}"
            },
            "url": "{{baseUrl}}/api/v1/verifications",
            "description": "Create an OTP verification and send (or sandbox-capture) the code."
          },
          "response": []
        },
        {
          "name": "Create verification (magic link)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 201) {",
                  "  const json = pm.response.json();",
                  "  if (json.id) {",
                  "    pm.collectionVariables.set('verificationId', json.id);",
                  "  }",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"identifier\": \"{{identifier}}\",\n  \"channel\": \"EMAIL\",\n  \"kind\": \"MAGIC_LINK\",\n  \"redirectUrl\": \"{{redirectUrl}}\"\n}"
            },
            "url": "{{baseUrl}}/api/v1/verifications",
            "description": "Create a magic-link verification with redirect URL."
          },
          "response": []
        },
        {
          "name": "Create verification (OTP SMS)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 201) {",
                  "  const json = pm.response.json();",
                  "  if (json.id) pm.collectionVariables.set('verificationId', json.id);",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"identifier\": \"+15551234567\",\n  \"channel\": \"SMS\",\n  \"kind\": \"OTP\"\n}"
            },
            "url": "{{baseUrl}}/api/v1/verifications",
            "description": "Create an OTP verification via SMS (E.164 phone required)."
          },
          "response": []
        },
        {
          "name": "Get verification status",
          "request": {
            "method": "GET",
            "url": "{{baseUrl}}/api/v1/verifications/{{verificationId}}",
            "description": "Poll verification status by ID. Set `verificationId` or run Create verification first."
          },
          "response": []
        },
        {
          "name": "Check OTP",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"token\": \"{{otpToken}}\"\n}"
            },
            "url": "{{baseUrl}}/api/v1/verifications/{{verificationId}}/check",
            "description": "Submit the OTP code for a verification."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Signals",
      "item": [
        {
          "name": "Precheck identifier",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"identifier\": \"{{identifier}}\",\n  \"channel\": \"EMAIL\"\n}"
            },
            "url": "{{baseUrl}}/api/v1/signals/precheck",
            "description": "Fraud/risk score before sending a verification."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Sandbox",
      "item": [
        {
          "name": "Get sandbox inbox",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.response.code === 200) {",
                  "  const json = pm.response.json();",
                  "  const msg = json.messages && json.messages[0];",
                  "  if (msg && msg.otp) {",
                  "    pm.collectionVariables.set('otpToken', msg.otp);",
                  "    console.log('Saved otpToken from inbox:', msg.otp);",
                  "  }",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/api/v1/sandbox/inbox/{{identifier}}?limit={{inboxLimit}}",
              "host": ["{{baseUrl}}"],
              "path": ["api", "v1", "sandbox", "inbox", "{{identifier}}"],
              "query": [
                {
                  "key": "limit",
                  "value": "{{inboxLimit}}"
                }
              ]
            },
            "description": "List captured sandbox messages. Auto-saves latest OTP to `otpToken`."
          },
          "response": []
        },
        {
          "name": "Get latest magic link",
          "request": {
            "method": "GET",
            "url": "{{baseUrl}}/api/v1/sandbox/inbox/{{identifier}}/latest-link",
            "description": "Most recent magic link for an identifier (sandbox only)."
          },
          "response": []
        },
        {
          "name": "Advance sandbox clock",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"seconds\": {{sandboxClockSeconds}}\n}"
            },
            "url": "{{baseUrl}}/api/v1/sandbox/clock",
            "description": "Fast-forward sandbox time by N seconds."
          },
          "response": []
        },
        {
          "name": "Reset sandbox clock",
          "request": {
            "method": "DELETE",
            "url": "{{baseUrl}}/api/v1/sandbox/clock",
            "description": "Reset sandbox clock to real time."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Health",
      "item": [
        {
          "name": "Health check",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "url": "{{baseUrl}}/api/health",
            "description": "Returns 200 if the API is reachable."
          },
          "response": []
        }
      ]
    }
  ]
}
