Authentication | Near Space Labs Docs

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

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

Token Response

{
  "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

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]}...")
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)}...`));
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:

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

Response:

{
  "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:

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.

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()
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