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

# Getting Started with API Keys

> Learn how to create and manage API keys for programmatic access to your distributor account

## Introduction

API keys allow you to interact with the Universal Wallet platform programmatically, enabling automation and integration with your existing systems. This tutorial will guide you through creating your first API key and making your first API request.

<Note>
  API keys provide direct access to your distributor account. Keep them secure and never share them publicly or commit them to version control.
</Note>

## Prerequisites

Before you begin, ensure you have:

* An active distributor account
* The **maker** role for creating API keys
* The **checker** role for approving API keys (can be a different user)

## Step 1: Create an API Key (Maker)

<Steps>
  <Step title="Navigate to API Keys">
    Log in to your distributor account and navigate to **Settings** → **API Keys**.
  </Step>

  <Step title="Click 'New API Key'">
    Click the **New API Key** button to start creating a new key.
  </Step>

  <Step title="Configure Permissions">
    Fill in the API key details:

    **Label**: Give your key a descriptive name (e.g., "POS Integration", "Balance Monitor")

    **Permissions**:

    * ✅ **Read Balance**: Query your distributor wallet balance
    * ✅ **Read Transactions**: Access operation history
    * ⬜ **Perform Operations**: Create cash-in/cash-out operations

    <Warning>
      Only enable "Perform Operations" if you're building a trusted integration. This permission allows creating financial transactions.
    </Warning>
  </Step>

  <Step title="Set Limits (Optional)">
    Configure optional security limits:

    * **Max Transaction Amount**: Maximum amount per operation (e.g., 100,000)
    * **Max Daily Volume**: Total daily transaction limit (e.g., 1,000,000)
    * **Allowed IPs**: Comma-separated list of IP addresses (e.g., `192.168.1.100,10.0.0.5`)
    * **Expires In**: Number of days until the key expires (default: 365)

    <Tip>
      Setting stricter limits reduces risk if the key is compromised.
    </Tip>
  </Step>

  <Step title="Submit for Approval">
    Click **Create API Key**. The key will be created and sent for approval by a checker.

    <Note>
      Due to the maker-checker pattern, you cannot approve your own API key request.
    </Note>
  </Step>
</Steps>

## Step 2: Approve the API Key (Checker)

<Steps>
  <Step title="Navigate to Pending API Keys">
    Have a user with the **checker** role log in and navigate to **Settings** → **API Keys** → **Pending** tab.
  </Step>

  <Step title="Review the Request">
    Review the API key request details:

    * Label and permissions
    * Transaction limits
    * IP restrictions
    * Expiration period
  </Step>

  <Step title="Approve or Reject">
    Click **Approve** to activate the key, or **Reject** if the request should not be approved.
  </Step>
</Steps>

## Step 3: Save Your API Key

<Warning>
  **Important**: The API key is displayed only once after approval. You must copy and save it securely.
</Warning>

Once approved, the maker will see a modal displaying the API key:

```
uwk_DlbWVU3Vjd11Le43kka6enGNjyd6xtbrBkNHMngl2aNz2Cm7
```

Copy this key and store it securely. You'll need it for all API requests.

## Step 4: Test Your API Key

Let's make your first API request to verify the key works.

### Get Distributor Balance

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.yourdomain.com/api/v1/distributors/{distributorID}/balance" \
    -H "Authorization: Bearer uwk_YOUR_API_KEY_HERE"
  ```

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

  const distributorID = 'your-distributor-id';
  const apiKey = 'uwk_YOUR_API_KEY_HERE';

  axios.get(`https://api.yourdomain.com/api/v1/distributors/${distributorID}/balance`, {
    headers: {
      'Authorization': `Bearer ${apiKey}`
    }
  })
  .then(response => {
    console.log('Balance:', response.data.balance);
  })
  .catch(error => {
    console.error('Error:', error.response.data);
  });
  ```

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

  distributor_id = 'your-distributor-id'
  api_key = 'uwk_YOUR_API_KEY_HERE'

  response = requests.get(
      f'https://api.yourdomain.com/api/v1/distributors/{distributor_id}/balance',
      headers={'Authorization': f'Bearer {api_key}'}
  )

  if response.status_code == 200:
      print('Balance:', response.json()['balance'])
  else:
      print('Error:', response.json())
  ```

  ```php PHP theme={null}
  <?php
  $distributorID = 'your-distributor-id';
  $apiKey = 'uwk_YOUR_API_KEY_HERE';

  $ch = curl_init("https://api.yourdomain.com/api/v1/distributors/$distributorID/balance");
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      "Authorization: Bearer $apiKey"
  ]);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  $data = json_decode($response, true);

  echo 'Balance: ' . $data['balance'];
  ?>
  ```
</CodeGroup>

### Expected Response

```json theme={null}
{
  "balance": "50000.00"
}
```

## Managing API Keys

### View Active Keys

Navigate to **Settings** → **API Keys** → **Active** to see all active keys, including:

* Label
* Permissions
* Usage statistics
* Last used timestamp
* Expiration date

### Revoke an API Key

If a key is compromised or no longer needed:

<Steps>
  <Step title="Create Revocation Request (Maker)">
    Click the **Revoke** button next to the key and provide a reason.
  </Step>

  <Step title="Approve Revocation (Checker)">
    A checker must approve the revocation request in the **Pending Revocations** tab.
  </Step>
</Steps>

<Warning>
  Revoked keys cannot be reactivated. Create a new key if needed.
</Warning>

## Best Practices

<AccordionGroup>
  <Accordion title="Use Descriptive Labels">
    Always use clear, descriptive labels that indicate the purpose and location of the key usage (e.g., "Production POS - Main Store", "Staging - Balance Monitor").
  </Accordion>

  <Accordion title="Principle of Least Privilege">
    Only grant the minimum permissions required. If you only need to check balances, don't enable "Perform Operations".
  </Accordion>

  <Accordion title="Set Transaction Limits">
    Always configure transaction and daily volume limits to minimize potential damage if a key is compromised.
  </Accordion>

  <Accordion title="Use IP Whitelisting">
    If your integration runs from fixed IP addresses, restrict the key to those IPs only.
  </Accordion>

  <Accordion title="Rotate Keys Regularly">
    Set appropriate expiration periods and create new keys before old ones expire. Consider rotating keys every 90-180 days.
  </Accordion>

  <Accordion title="Secure Storage">
    * Never hard-code keys in your application
    * Use environment variables or secure secret management systems
    * Never commit keys to version control
    * Restrict access to production keys
  </Accordion>

  <Accordion title="Monitor Usage">
    Regularly review API key usage in the dashboard. Investigate any unexpected patterns or usage from unknown IPs.
  </Accordion>
</AccordionGroup>

## Troubleshooting

### 401 Unauthorized

* Verify the API key is correct and hasn't been revoked
* Ensure you're using the `Bearer` prefix in the Authorization header
* Check that the key hasn't expired

### 403 Forbidden

* Confirm the key has the required permission for the endpoint
* Verify the distributor ID in the URL matches the distributor ID associated with the key
* If using IP whitelisting, ensure your request originates from an allowed IP

### 400 Bad Request

* Check that you're using the correct endpoint URL
* Verify request payload format matches the API specification
* Ensure required parameters are included

## Next Steps

<CardGroup cols={2}>
  <Card title="Cash-In via API" icon="arrow-up" href="/distributors/api-tutorials/cash-in">
    Learn how to create cash-in operations programmatically
  </Card>

  <Card title="Cash-Out via API" icon="arrow-down" href="/distributors/api-tutorials/cash-out">
    Learn how to process cash-out operations via API
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/distributors/authentication">
    Full API endpoint documentation
  </Card>

  <Card title="Security Best Practices" icon="shield" href="/concepts/security">
    Learn about securing your integration
  </Card>
</CardGroup>
