Authentication
Exchange your NSL client credentials for a short-lived OAuth token. Reuse it for every subsequent request until it expires.
How It Works
- Call
POST /oauth/tokenwith your NSL client id + secret. - Cache the token for 60 minutes; refresh proactively at ~55 minutes.
- Send
Authorization: Bearer <token>on every downstream request.
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. |
Refresh when current_time > token_issued_at + expires_in - 300 to keep a 5‑minute safety buffer.
Code Examples
- Python
- JavaScript
- Bash
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.
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.
- Python
- Bash
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