On this page

Exchange your NSL client credentials for a short-lived OAuth token. Reuse it for every subsequent request until it expires.

## How It Works

1. Call `POST /oauth/token` with your NSL client id + secret.
2. Cache the token for 60 minutes; refresh proactively at ~55 minutes.
3. Send `Authorization: Bearer <token>` on every downstream request.

tip

Tokens last 60 minutes. Prepare to refresh before they expire to avoid 401s.

## Token Request Payload

```json
{
  "client_id": "<your NSL client id>",
  "client_secret": "<your NSL client secret>",
  "audience": "https://api.nearspacelabs.com",
  "grant_type": "client_credentials"
}
```

## Token Response

```json
{
  "access_token": "eyJ...",
  "expires_in": 3600,
  "token_type": "Bearer"
}
```

| Field        | Description                                                                                   |
|--------------|-----------------------------------------------------------------------------------------------|
| `access_token` | Pass this as `Authorization: Bearer <access_token>` on every downstream request.            |
| `expires_in`   | Seconds until the token expires (typically `3600`). Use this to schedule refreshes.         |
| `token_type`   | Always `Bearer`.                                                                             |
|

tip

Refresh when `current_time > token_issued_at + expires_in - 300` to keep a 5‑minute safety buffer.

## Code Examples

- Python
- JavaScript
- Bash

```python
import requests

NSL_ID = "YOUR NSL ID"
NSL_SECRET = "YOUR NSL SECRET"

def get_auth_token():
    auth_headers = {'content-type': 'application/json'}
    post_body = {
        'client_id': NSL_ID,
        'client_secret': NSL_SECRET,
        'audience': 'https://api.nearspacelabs.com',
        'grant_type': 'client_credentials'
    }
    req = requests.post(
        'https://api.nearspacelabs.net/oauth/token',
        json=post_body,
        headers=auth_headers
    )
    req.raise_for_status()
    return req.json()['access_token']

auth_token = get_auth_token()
print(f"Token acquired: {auth_token[:20]}...")
```

```javascript
const fetch = require('node-fetch');

const NSL_ID = "YOUR NSL ID";
const NSL_SECRET = "YOUR NSL SECRET";

async function getAuthToken() {
  const authHeaders = { 'Content-Type': 'application/json' };
  const postBody = {
    client_id: NSL_ID,
    client_secret: NSL_SECRET,
    audience: 'https://api.nearspacelabs.com',
    grant_type: 'client_credentials'
  };

const response = await fetch('https://api.nearspacelabs.net/oauth/token', {
    method: 'POST',
    headers: authHeaders,
    body: JSON.stringify(postBody)
  });

if (!response.ok) {
    throw new Error(`HTTP error! Status: ${response.status}`);
  }

const data = await response.json();
  return data.access_token;
}

getAuthToken().then(token => console.log(`Token: ${token.slice(0, 20)}...`));
```

```bash
TOKEN=$(curl -s -X POST https://api.nearspacelabs.net/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR NSL ID",
    "client_secret": "YOUR NSL SECRET",
    "audience": "https://api.nearspacelabs.com",
    "grant_type": "client_credentials"
  }' | jq -r '.access_token')

echo "Token: ${TOKEN:0:20}..."
```

## Static API Keys (Long-Lived)

When you can't refresh a 60‑minute token on every request — embedding tiles in a web map, sharing a demo, or wiring up a client with no token-refresh logic — issue a **static API key** instead. It's the same kind of signed JWT, but valid for **1 year**, and you pass it as an `api_key` query parameter rather than an `Authorization` header.

caution

A static key is a bearer credential that lives for a year and travels in the URL, where it can end up in server logs and browser history. Treat it like a password and reissue it if it leaks.

### Issuing a Key

Call `POST /oauth/static_key` with the same NSL client id + secret you use for OAuth:

```json
{
  "client_id": "<your NSL client id>",
  "client_secret": "<your NSL client secret>"
}
```

Response:

```json
{
  "api_key": "eyJ...",
  "expires_in": 31536000,
  "token_type": "Bearer"
}
```

| Field         | Description                                                                                   |
|---------------|-----------------------------------------------------------------------------------------------|
| `api_key`     | The long-lived JWT. Pass it as `?api_key=<api_key>` on downstream requests.                 |
| `expires_in`  | Seconds until the key expires (`31536000` = 1 year).                                        |
| `token_type`  | Always `Bearer`.                                                                             |
|
### Using a Key

Append the key as a query parameter to any authenticated request — no `Authorization` header needed:

```text
https://api.nearspacelabs.net/tile/v2/{surveyid}/{z}/{x}/{y}?api_key=<api_key>
```

The key carries the same permissions and contract as your OAuth tokens, so it works anywhere a Bearer token does.

- Python
- Bash

```python
import requests

NSL_ID = "YOUR NSL ID"
NSL_SECRET = "YOUR NSL SECRET"

# Issue once, then reuse it for up to a year
resp = requests.post(
    'https://api.nearspacelabs.net/oauth/static_key',
    json={'client_id': NSL_ID, 'client_secret': NSL_SECRET},
)
resp.raise_for_status()
api_key = resp.json()['api_key']

# Pass it as a query parameter — no Authorization header required
tile_url = 'https://api.nearspacelabs.net/tile/v2/2024Q4-FL-PTCH/18/71276/110648'
img = requests.get(tile_url, params={'api_key': api_key})
img.raise_for_status()
```

```bash
API_KEY=$(curl -s -X POST https://api.nearspacelabs.net/oauth/static_key \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR NSL ID",
    "client_secret": "YOUR NSL SECRET"
  }' | jq -r '.api_key')

curl -s "https://api.nearspacelabs.net/tile/v2/2024Q4-FL-PTCH/18/71276/110648?api_key=${API_KEY}" \
  -o tile.png
```
