SnipyDevelopers
Authentication

Authentication

The Snipy API supports two authentication methods: API Key authentication for server-to-server integrations, and OAuth 2.0 token exchange for user-facing applications.

API Key Authentication

API keys are the simplest way to authenticate with the Snipy API. They are best suited for server-side integrations where you control the environment.

Using your API key

Pass your API key in the X-API-Key header with every request.

cURL
curl -X GET https://api.snipy.com/api/urls \
  -H "X-API-Key: snpy_a1b2c3d4e5f6..."

Key format

PropertyValue
Prefixsnpy_
Formatsnpy_ + 64 hexadecimal characters
Max keys per account10
StorageSHA-256 hashed (never stored in plain text)

Scopes

API keys can be created with specific scopes to limit access. Available scopes:

ScopeDescription
qr:readRead access to QR code endpoints
qr:writeWrite access to QR code endpoints (create, update, delete)

More scopes are being added. Keys without scopes have full access to all endpoints.

Code examples

JavaScript (fetch)
const response = await fetch("https://api.snipy.com/api/urls", {
  headers: {
    "X-API-Key": "snpy_a1b2c3d4e5f6...",
  },
});

const data = await response.json();
console.log(data);
Python (requests)
import requests

response = requests.get(
    "https://api.snipy.com/api/urls",
    headers={"X-API-Key": "snpy_a1b2c3d4e5f6..."}
)

data = response.json()
print(data)

OAuth 2.0 Token Exchange

For user-facing applications, use OAuth 2.0 token exchange to obtain access and refresh tokens. Pass the access token as a Bearer token in the Authorization header.

Obtain an access token

Exchange user credentials for an access token using the password grant type.

cURL
curl -X POST https://api.snipy.com/api/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password" \
  -d "identifier=user@example.com" \
  -d "password=your_password"

Response

200 OK
{
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "dGhpcyBpcyBhIHJlZnJl...",
  "expires_in": 86400,
  "token_type": "Bearer"
}

Using the access token

cURL
curl -X GET https://api.snipy.com/api/urls \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Refresh a token

When the access token expires, use the refresh token to obtain a new one.

cURL
curl -X POST https://api.snipy.com/api/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=dGhpcyBpcyBhIHJlZnJl..."

Two-factor authentication

If the user has 2FA enabled, the initial token request will return a challenge. Complete the flow by submitting the TOTP code.

Challenge Response
{
  "error": 0,
  "data": {
    "twofa_required": true,
    "challenge_token": "ch_abc123..."
  }
}
Complete 2FA
curl -X POST https://api.snipy.com/api/token/2fa \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "challenge_token=ch_abc123..." \
  -d "code=123456"

Revoke a token

Invalidate an access token when the user signs out or the token is compromised.

cURL
curl -X POST https://api.snipy.com/api/revoke \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Code examples

JavaScript
async function getAccessToken(email, password) {
  const response = await fetch("https://api.snipy.com/api/token", {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "password",
      identifier: email,
      password: password,
    }),
  });

  const data = await response.json();

  if (data.data?.twofa_required) {
    // Handle 2FA challenge
    return { challenge: data.data.challenge_token };
  }

  return {
    accessToken: data.access_token,
    refreshToken: data.refresh_token,
  };
}
Python
import requests

def get_access_token(email: str, password: str) -> dict:
    response = requests.post(
        "https://api.snipy.com/api/token",
        data={
            "grant_type": "password",
            "identifier": email,
            "password": password,
        },
    )
    data = response.json()

    if data.get("data", {}).get("twofa_required"):
        return {"challenge": data["data"]["challenge_token"]}

    return {
        "access_token": data["access_token"],
        "refresh_token": data["refresh_token"],
    }

Security best practices

  • --Never expose API keys in client-side code or public repositories.
  • --Use environment variables to store your keys.
  • --Rotate keys periodically and revoke any compromised keys immediately.
  • --Use the most restrictive scopes possible for your use case.
  • --Always make requests over HTTPS. HTTP requests will be rejected.