Authorization headers
TAPI v3 supports authentication via the Authorization header as an alternative to including credentials in the request body. This guide explains how to implement Authorization header authentication for your TAPI integrations.
Benefits of Authorization Header
- Improved Security: Credentials are separated from business data, reducing accidental exposure when sharing request examples
- Cleaner Request Bodies: Keep your request payloads focused on business logic only
- Industry Standard: Aligns with REST API best practices
- Debugging Safety: Share request bodies with team members without worrying about credential exposure
Authorization Header
Required Header Format
TAPI uses the standard Authorization header with a Bearer token format:
| Header | Format | Example |
|---|---|---|
Authorization | Bearer {clientID}:{apiKey} | Authorization: Bearer NC12345:sk_live_abc123xyz789 |
Important Notes
- The format is
Bearerfollowed by a space, thenclientID:apiKeyseparated by a colon - Header names are case-insensitive (per HTTP specification)
- The Authorization header takes precedence over body parameters if both are provided
- The Bearer token must contain both clientID and apiKey separated by a colon (:)
- GET endpoints REQUIRE the Authorization header - credentials cannot be passed in URL parameters
Migration Guide
Before (Body Authentication)
{
"developerAPIKey": "sk_live_abc123xyz789",
"clientID": "NC12345",
"accountId": "A12345",
"amount": 1000
}After (Authorization Header)
Headers:
Authorization: Bearer NC12345:sk_live_abc123xyz789
Content-Type: application/json
Body:
{
"accountId": "A12345",
"amount": 1000
}GET Endpoints (Authorization Header Required)
For GET endpoints, authentication MUST be provided via the Authorization header since there's no request body:
# GET endpoints require Authorization header
curl -X GET https://api-sandboxdash.norcapsecurities.com/tapiv3/parties \
-H "Authorization: Bearer NC12345:sk_live_abc123xyz789"
# These endpoints include: parties, entities, trades, offerings, issuers, links, exports, jobs, permissionsImplementation Examples
cURL
curl -X POST https://api-sandboxdash.norcapsecurities.com/tapiv3/createTrade \
-H "Content-Type: application/json" \
-H "Authorization: Bearer NC12345:sk_live_abc123xyz789" \
-d '{
"accountId": "A12345",
"offeringId": "O54321",
"units": 100
}'JavaScript (Fetch API)
const response = await fetch('https://api-sandboxdash.norcapsecurities.com/tapiv3/createTrade', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer NC12345:sk_live_abc123xyz789'
},
body: JSON.stringify({
accountId: 'A12345',
offeringId: 'O54321',
units: 100
})
});JavaScript (Axios)
const axios = require('axios');
const response = await axios.post(
'https://api-sandboxdash.norcapsecurities.com/tapiv3/createTrade',
{
accountId: 'A12345',
offeringId: 'O54321',
units: 100
},
{
headers: {
'Authorization': 'Bearer NC12345:sk_live_abc123xyz789'
}
}
);Python (Requests)
import requests
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer NC12345:sk_live_abc123xyz789'
}
data = {
'accountId': 'A12345',
'offeringId': 'O54321',
'units': 100
}
response = requests.post(
'https://api-sandboxdash.norcapsecurities.com/tapiv3/createTrade',
headers=headers,
json=data
)PHP (cURL)
$ch = curl_init('https://api-sandboxdash.norcapsecurities.com/tapiv3/createTrade');
$headers = [
'Content-Type: application/json',
'Authorization: Bearer NC12345:sk_live_abc123xyz789'
];
$data = [
'accountId' => 'A12345',
'offeringId' => 'O54321',
'units' => 100
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);C# (.NET HttpClient)
using System.Net.Http;
using System.Text;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer NC12345:sk_live_abc123xyz789");
var data = new
{
accountId = "A12345",
offeringId = "O54321",
units = 100
};
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://api-sandboxdash.norcapsecurities.com/tapiv3/createTrade",
content
);Java (OkHttp)
import okhttp3.*;
OkHttpClient client = new OkHttpClient();
String json = "{\"accountId\":\"A12345\",\"offeringId\":\"O54321\",\"units\":100}";
RequestBody body = RequestBody.create(
json,
MediaType.parse("application/json")
);
Request request = new Request.Builder()
.url("https://api-sandboxdash.norcapsecurities.com/tapiv3/createTrade")
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer NC12345:sk_live_abc123xyz789")
.post(body)
.build();
Response response = client.newCall(request).execute();Ruby (Net::HTTP)
require 'net/http'
require 'json'
uri = URI('https://api-sandboxdash.norcapsecurities.com/tapiv3/createTrade')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer NC12345:sk_live_abc123xyz789'
request.body = {
accountId: 'A12345',
offeringId: 'O54321',
units: 100
}.to_json
response = http.request(request)Backwards Compatibility
Both Methods Supported
Both authentication methods are supported:
- Authorization Header (Recommended, REQUIRED for GET endpoints)
- Body Parameters (POST/PUT only, not available for GET)
Method Availability by HTTP Verb
| HTTP Method | Header Auth | Body Auth | Notes |
|---|---|---|---|
| GET | ✅ Required | ❌ N/A | No request body in GET requests |
| POST | ✅ Supported | ✅ Supported | Header auth recommended |
| PUT | ✅ Supported | ✅ Supported | Header auth recommended |
| DELETE | ✅ Supported | ✅ Supported | Header auth recommended |
Priority Order
If credentials are provided in both headers and body (POST/PUT only):
- Headers take precedence
- Body credentials are ignored
Example with Both
# Authorization header will be used, body credentials ignored
curl -X POST https://api-sandboxdash.norcapsecurities.com/tapiv3/getAccount \
-H "Authorization: Bearer NC12345:sk_live_abc123xyz789" \
-d '{
"developerAPIKey": "old_key_ignored",
"clientID": "old_id_ignored",
"accountId": "A12345"
}'Error Handling
Missing Headers
If authentication headers are missing and no body credentials are provided:
{
"statusCode": 103,
"statusDesc": "Invalid developer API Key"
}Invalid Credentials
If the provided credentials (header or body) are invalid:
{
"statusCode": 103,
"statusDesc": "Invalid developer API Key"
}Unauthorized Access
If credentials are valid but lack permission for the requested operation:
{
"statusCode": 110,
"statusDesc": "You do not have the required permissions"
}Best Practices
1. Environment Variables
Store credentials in environment variables, not in code:
// Good
const apiKey = process.env.TAPI_API_KEY;
const clientId = process.env.TAPI_CLIENT_ID;
// Bad
const apiKey = 'sk_live_abc123xyz789'; // Never hardcode!2. Configuration Management
Create a centralized configuration for API calls:
// config.js
module.exports = {
baseURL: 'https://api-sandboxdash.norcapsecurities.com/tapiv3',
headers: {
'Authorization': `Bearer ${process.env.TAPI_CLIENT_ID}:${process.env.TAPI_API_KEY}`
}
};
// usage.js
const config = require('./config');
const axios = require('axios');
const client = axios.create({
baseURL: config.baseURL,
headers: config.headers
});
// Now all requests automatically include auth headers
const response = await client.post('/createTrade', {
accountId: 'A12345',
offeringId: 'O54321',
units: 100
});3. Error Handling
Always handle authentication errors gracefully:
try {
const response = await makeApiCall();
// Process successful response
} catch (error) {
if (error.response?.status === 401) {
console.error('Authentication failed. Check your API credentials.');
} else if (error.response?.status === 403) {
console.error('Permission denied. Your API key may lack required scopes.');
} else {
console.error('API call failed:', error.message);
}
}4. Logging and Debugging
When logging requests, exclude sensitive headers:
// Create a sanitized request log
function logRequest(config) {
const sanitized = {
...config,
headers: {
...config.headers,
'Authorization': 'Bearer ***REDACTED***'
}
};
console.log('API Request:', sanitized);
}Testing Your Implementation
1. Test Environment
Start with the sandbox environment:
- Sandbox URL:
https://api-sandboxdash.norcapsecurities.com/tapiv3 - Use your sandbox credentials
2. Verify Headers Are Sent
Use a tool like curl with -v flag to see headers:
curl -v -X POST https://api-sandboxdash.norcapsecurities.com/tapiv3/ping \
-H "Authorization: Bearer your_sandbox_id:your_sandbox_key"3. Gradual Migration
- Update one endpoint to use headers
- Test thoroughly
- Update remaining endpoints
- Remove body credentials once all endpoints are updated
Frequently Asked Questions
Q: Is Authorization header authentication available in all environments?
A: Authorization header support varies by environment. Check with your account manager or test in your sandbox environment to confirm availability.
Q: Will my existing integrations break?
A: No. Body-based authentication will continue to work for POST/PUT/DELETE requests. However, GET endpoints require header authentication since they don't have request bodies.
Q: Do I need to update my GET endpoint calls?
A: Yes. All GET endpoints require the Authorization header. You cannot pass credentials as URL parameters for security reasons.
Q: Can I use different authentication methods for different endpoints?
A: Yes. You can use headers for some calls and body parameters for others. Each request is authenticated independently.
Q: Is the header name case-sensitive?
A: No. HTTP headers are case-insensitive. Authorization, authorization, and AUTHORIZATION all work.
Q: What if I accidentally send credentials in both headers and body?
A: Headers take precedence. Body credentials will be ignored if headers are present.
Q: Do webhook endpoints require these headers?
A: No. Webhook endpoints (callbacks from external services like DocuSign) have their own authentication mechanisms.
Support
For questions or issues with header authentication:
- Technical Support: [email protected]
- API Documentation: [https://api-sandboxdash.norcapsecurities.com/documentation]
- Status Page: [https://status.northcapital.com]
Updated 3 days ago
