> ## Documentation Index
> Fetch the complete documentation index at: https://docs.easyotp.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Get started with EasyOTP in 5 minutes

## Overview

This guide will walk you through sending your first OTP and verifying it. You'll learn the basic workflow that powers all OTP verification in your applications.

## Step 1: Get Your API Key

<Steps>
  <Step title="Sign up for an account">
    Go to [app.easyotp.dev/signup](https://app.easyotp.dev/signup) and create your account.
  </Step>

  <Step title="Navigate to API Keys">
    Once logged in, go to the API Keys section in your dashboard.
  </Step>

  <Step title="Create a new API key">
    Click "Create API Key" and give it a descriptive name. Copy and save your key securely.
  </Step>
</Steps>

<Warning>
  Store your API key securely! It provides access to your account and cannot be retrieved after creation.
</Warning>

## Step 2: Send Your First OTP

Choose your preferred method:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://app.easyotp.dev/api/v1/send \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "channel": "sms",
      "recipient": "+1234567890",
      "message": "Your verification code is: {code}",
      "expires_in": 300
    }'
  ```

  ```javascript Node.js (SDK) theme={null}
  import { EasyOTP } from '@easy-otp/sdk';

  const client = new EasyOTP({
    apiKey: 'YOUR_API_KEY'
  });

  const result = await client.send({
    channel: 'sms',
    recipient: '+1234567890',
    message: 'Your verification code is: {code}',
    expires_in: 300
  });

  console.log(result);
  ```

  ```javascript Node.js (Fetch) theme={null}
  const response = await fetch('https://app.easyotp.dev/api/v1/send', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      channel: 'sms',
      recipient: '+1234567890',
      message: 'Your verification code is: {code}',
      expires_in: 300
    })
  });

  const data = await response.json();
  console.log(data);
  ```

  ```python Python (SDK) theme={null}
  from easyotp import EasyOTP

  client = EasyOTP(api_key='YOUR_API_KEY')

  result = client.send(
      channel='sms',
      recipient='+1234567890',
      message='Your verification code is: {code}',
      expires_in=300
  )

  print(result)
  ```

  ```python Python (Requests) theme={null}
  import requests

  response = requests.post(
      'https://app.easyotp.dev/api/v1/send',
      headers={
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json',
      },
      json={
          'channel': 'sms',
          'recipient': '+1234567890',
          'message': 'Your verification code is: {code}',
          'expires_in': 300
      }
  )

  data = response.json()
  print(data)
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "net/http"
  )

  func main() {
      payload := map[string]interface{}{
          "channel": "sms",
          "recipient": "+1234567890",
          "message": "Your verification code is: {code}",
          "expires_in": 300,
      }
      
      jsonData, _ := json.Marshal(payload)
      
      req, _ := http.NewRequest("POST", "https://app.easyotp.dev/api/v1/send", bytes.NewBuffer(jsonData))
      req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
      req.Header.Set("Content-Type", "application/json")
      
      client := &http.Client{}
      resp, _ := client.Do(req)
      defer resp.Body.Close()
  }
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "success": true,
  "verification_id": "11f951d5-32d1-4b49-bdda-7da248e2615c",
  "expires_at": "2024-01-01T12:05:00.000Z",
  "request_id": "7b4d6022-7260-4568-b6b7-29c366c47bbc"
}
```

Save the `verification_id` - you'll need it to verify the code.

## Step 3: Verify the Code

When your user enters the code they received, verify it:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://app.easyotp.dev/api/v1/verify \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "verification_id": "11f951d5-32d1-4b49-bdda-7da248e2615c",
      "code": "123456"
    }'
  ```

  ```javascript Node.js (SDK) theme={null}
  import { EasyOTP } from '@easy-otp/sdk';

  const client = new EasyOTP({
    apiKey: 'YOUR_API_KEY'
  });

  const result = await client.verify({
    verification_id: '11f951d5-32d1-4b49-bdda-7da248e2615c',
    code: '123456'
  });

  console.log(result);
  ```

  ```javascript Node.js (Fetch) theme={null}
  const response = await fetch('https://app.easyotp.dev/api/v1/verify', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      verification_id: '11f951d5-32d1-4b49-bdda-7da248e2615c',
      code: '123456'
    })
  });

  const data = await response.json();
  console.log(data);
  ```

  ```python Python (SDK) theme={null}
  from easyotp import EasyOTP

  client = EasyOTP(api_key='YOUR_API_KEY')

  result = client.verify(
      verification_id='11f951d5-32d1-4b49-bdda-7da248e2615c',
      code='123456'
  )

  print(result)
  ```

  ```python Python (Requests) theme={null}
  import requests

  response = requests.post(
      'https://app.easyotp.dev/api/v1/verify',
      headers={
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json',
      },
      json={
          'verification_id': '11f951d5-32d1-4b49-bdda-7da248e2615c',
          'code': '123456'
      }
  )

  data = response.json()
  print(data)
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "net/http"
  )

  func main() {
      payload := map[string]interface{}{
          "verification_id": "11f951d5-32d1-4b49-bdda-7da248e2615c",
          "code": "123456",
      }
      
      jsonData, _ := json.Marshal(payload)
      
      req, _ := http.NewRequest("POST", "https://app.easyotp.dev/api/v1/verify", bytes.NewBuffer(jsonData))
      req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
      req.Header.Set("Content-Type", "application/json")
      
      client := &http.Client{}
      resp, _ := client.Do(req)
      defer resp.Body.Close()
  }
  ```
</CodeGroup>

### Response

```json theme={null}
{
  "success": true,
  "verified": true,
  "message": "Code verified successfully",
  "request_id": "7b4d6022-7260-4568-b6b7-29c366c47bbc"
}
```

## Understanding Channels

EasyOTP supports three channels:

<CardGroup cols={3}>
  <Card title="SMS" icon="message">
    Send codes via text message. Recipient must be a valid E.164 phone number (e.g., +1234567890).
  </Card>

  <Card title="Email" icon="envelope">
    Send codes via email. Supports custom subject lines for better branding.
  </Card>

  <Card title="Voice" icon="phone">
    Deliver codes via automated voice call. Great for accessibility and international users.
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="JavaScript SDK" icon="code" href="/api-reference/sdk">
    Use our official JavaScript SDK
  </Card>

  <Card title="Python SDK" icon="code" href="/api-reference/python-sdk">
    Use our official Python SDK
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Explore the complete API documentation
  </Card>

  <Card title="View Logs" icon="list" href="https://app.easyotp.dev/logs">
    Monitor your API usage and debug issues
  </Card>

  <Card title="Manage Credits" icon="coins" href="https://app.easyotp.dev/credits">
    Add credits to your account
  </Card>

  <Card title="Get Support" icon="life-ring" href="mailto:support@easyotp.dev">
    Need help? Contact our support team
  </Card>
</CardGroup>

## Best Practices

<AccordionGroup>
  <Accordion title="Store verification IDs securely">
    Keep verification IDs associated with user sessions server-side. Never expose them in URLs or client-side code.
  </Accordion>

  <Accordion title="Set appropriate expiration times">
    Use shorter expiration times (2-5 minutes) for sensitive operations. Longer times (10-15 minutes) are acceptable for email verification.
  </Accordion>

  <Accordion title="Customize your messages">
    Include your brand name and make messages clear. Good: "Your Acme Corp verification code is: {code}". Bad: "{code}".
  </Accordion>

  <Accordion title="Handle errors gracefully">
    Always check the response status and handle errors. Provide clear feedback to users when codes expire or are invalid.
  </Accordion>

  <Accordion title="Implement rate limiting">
    Limit how many codes users can request in a time period to prevent abuse and reduce costs.
  </Accordion>
</AccordionGroup>
