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

# API Integration

> Integrate with the Scanova API using HTTP requests in any programming language

## API-Based Integration

Scanova provides a **pure REST API** that can be integrated with any programming language using standard HTTP libraries. No SDKs or libraries are required—just make HTTP requests to our API endpoints.

<CardGroup cols={2}>
  <Card title="JavaScript/Node.js" icon="js" href="/essentials/code#javascript">
    Use fetch or axios to make API requests from Node.js or browser.
  </Card>

  <Card title="Python" icon="python" href="/essentials/code#python">
    Use requests library to integrate with Python applications.
  </Card>

  <Card title="PHP" icon="php" href="/essentials/code#php">
    Use cURL or Guzzle to make API requests from PHP.
  </Card>

  <Card title="cURL Examples" icon="terminal" href="/essentials/code">
    Ready-to-use cURL commands for testing and automation.
  </Card>
</CardGroup>

## Making API Requests

All API requests require authentication using your API key in the `Authorization` header. The base URL for all requests is `https://management.scanova.io`.

### JavaScript/Node.js

Using native `fetch`:

```javascript theme={null}
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://management.scanova.io';

// Create a QR code
async function createQRCode() {
  const response = await fetch(`${BASE_URL}/qr/`, {
    method: 'POST',
    headers: {
      'Authorization': API_KEY,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      name: 'My QR Code',
      category: '1',
      qr_type: 'dy',
      info: JSON.stringify({
        type: 'url',
        data: { url: 'https://scanova.io' }
      })
    })
  });
  
  const qrCode = await response.json();
  return qrCode;
}
```

Using `axios`:

```javascript theme={null}
const axios = require('axios');

const api = axios.create({
  baseURL: 'https://management.scanova.io',
  headers: {
    'Authorization': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  }
});

// Create a QR code
const qrCode = await api.post('/qr/', {
  name: 'My QR Code',
  category: '1',
  qr_type: 'dy',
  info: JSON.stringify({
    type: 'url',
    data: { url: 'https://scanova.io' }
  })
});
```

### Python

Using `requests` library:

```python theme={null}
import requests
import json

API_KEY = 'YOUR_API_KEY'
BASE_URL = 'https://management.scanova.io'

headers = {
    'Authorization': API_KEY,
    'Content-Type': 'application/json'
}

# Create a QR code
data = {
    'name': 'My QR Code',
    'category': '1',
    'qr_type': 'dy',
    'info': json.dumps({
        'type': 'url',
        'data': {'url': 'https://scanova.io'}
    })
}

response = requests.post(
    f'{BASE_URL}/qr/',
    headers=headers,
    json=data
)

qr_code = response.json()
```

### PHP

Using `cURL`:

```php theme={null}
<?php
$apiKey = 'YOUR_API_KEY';
$baseUrl = 'https://management.scanova.io';

$data = [
    'name' => 'My QR Code',
    'category' => '1',
    'qr_type' => 'dy',
    'info' => json_encode([
        'type' => 'url',
        'data' => ['url' => 'https://scanova.io']
    ])
];

$ch = curl_init($baseUrl . '/qr/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: ' . $apiKey,
    'Content-Type: application/json'
]);

$response = curl_exec($ch);
$qrCode = json_decode($response, true);
curl_close($ch);
```

Using `Guzzle`:

```php theme={null}
<?php
use GuzzleHttp\Client;

$client = new Client([
    'base_uri' => 'https://management.scanova.io',
    'headers' => [
        'Authorization' => 'YOUR_API_KEY',
        'Content-Type' => 'application/json'
    ]
]);

$response = $client->post('/qr/', [
    'json' => [
        'name' => 'My QR Code',
        'category' => '1',
        'qr_type' => 'dy',
        'info' => json_encode([
            'type' => 'url',
            'data' => ['url' => 'https://scanova.io']
        ])
    ]
]);

$qrCode = json_decode($response->getBody(), true);
```

## Webhooks

Set up real-time notifications for QR code events by configuring webhook endpoints in your Scanova dashboard.

```javascript theme={null}
// Express.js webhook handler
const express = require('express');
const crypto = require('crypto');
const app = express();

app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const signature = req.headers['x-scanova-signature'];
  const payload = req.body;
  const webhookSecret = 'YOUR_WEBHOOK_SECRET'; // From Scanova dashboard
  
  // Verify webhook signature
  const expectedSignature = crypto
    .createHmac('sha256', webhookSecret)
    .update(payload)
    .digest('hex');
  
  if (signature === expectedSignature) {
    const event = JSON.parse(payload.toString());
    
    switch (event.type) {
      case 'qr_code.scanned':
        console.log('QR code scanned:', event.data);
        break;
      case 'qr_code.created':
        console.log('QR code created:', event.data);
        break;
    }
    
    res.status(200).send('OK');
  } else {
    res.status(401).send('Invalid signature');
  }
});
```

## Rate Limits

The Scanova API has the following rate limits:

* **Free Plan**: 100 requests per minute
* **Pro Plan**: 1,000 requests per minute
* **Enterprise Plan**: 10,000 requests per minute

<Info>
  Rate limit headers are included in all API responses:

  * `X-RateLimit-Limit`: Maximum requests per minute
  * `X-RateLimit-Remaining`: Remaining requests in current window
  * `X-RateLimit-Reset`: Time when the rate limit resets
</Info>

## Best Practices

### Error Handling

Always handle API errors gracefully:

```javascript theme={null}
async function createQRCode(data) {
  try {
    const response = await fetch('https://management.scanova.io/qr/', {
      method: 'POST',
      headers: {
        'Authorization': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    });
    
    if (!response.ok) {
      const error = await response.json();
      if (response.status === 401) {
        throw new Error('Invalid API key');
      } else if (response.status === 429) {
        throw new Error('Rate limit exceeded');
      } else {
        throw new Error(error.message || 'API error');
      }
    }
    
    return await response.json();
  } catch (error) {
    console.error('Failed to create QR code:', error.message);
    throw error;
  }
}
```

### Retry Logic

Implement retry logic for transient failures:

```javascript theme={null}
async function createQRCodeWithRetry(data, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch('https://management.scanova.io/qr/', {
        method: 'POST',
        headers: {
          'Authorization': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
      });
      
      if (response.status === 429 && i < maxRetries - 1) {
        // Wait before retrying (exponential backoff)
        await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i)));
        continue;
      }
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      
      return await response.json();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
  }
}
```

## Testing

### Testing API Requests

For testing, you can use mock HTTP libraries or test against the API:

```javascript theme={null}
// Using fetch-mock for testing
import fetchMock from 'fetch-mock';

describe('QR Code Creation', () => {
  beforeEach(() => {
    fetchMock.reset();
  });
  
  it('should create a QR code', async () => {
    fetchMock.post('https://management.scanova.io/qr/', {
      status: 200,
      body: {
        id: 123,
        qrid: 'Qr123456789',
        name: 'Test QR Code'
      }
    });
    
    const qrCode = await createQRCode({
      name: 'Test QR Code',
      category: '1',
      qr_type: 'dy',
      info: JSON.stringify({ type: 'url', data: { url: 'https://example.com' } })
    });
    
    expect(qrCode.qrid).toBe('Qr123456789');
  });
});
```

## Support

<CardGroup cols={2}>
  <Card title="Email Support" icon="envelope" href="mailto:support@scanova.io">
    Contact our support team directly.
  </Card>

  <Card title="Documentation" icon="book" href="/api-reference/getting-started/introduction">
    Browse the complete API reference.
  </Card>
</CardGroup>
