Unified Messaging API Documentation
Version: 1.0.0
Base URL: https://apiaccess.digify.no/api/v1
🤖 Building an API client with AI?
Get the comprehensive Client Development Guide - optimized for Claude Code and other AI tools. Includes TypeScript types, example implementations in multiple languages, and best practices.
- View online: https://apiaccess.digify.no/client-guide
- Download markdown: https://apiaccess.digify.no/client-guide?format=md
#Authentication
All API endpoints (except health checks) require an AccessToken for authentication.
Methods to provide AccessToken:
1. Query parameter: ?AccessToken=YOUR_TOKEN
2. Header: X-Access-Token: YOUR_TOKEN
3. Header: Authorization: Bearer YOUR_TOKEN
Test Token: Contact administrator for access token
#Endpoints
#1. Send Messages
Send SMS and/or Email messages.
Endpoint: POST /api/v1/messages/send
Authentication: Required
Request Body:
{
"messages": [
{
"type": "sms",
"id": "optional-client-id",
"sourceAddr": "1234",
"destAddr": "4712345678",
"msg": "Hello from Unified Messaging API!",
"priority": 0,
"dataCoding": 1
},
{
"type": "email",
"sourceAddr": "noreply@example.com",
"sourceAddrName": "Example Service",
"destAddr": "user@example.com",
"subject": "Welcome",
"body": "<html><body><h1>Welcome!</h1></body></html>",
"bodyFormat": "html"
}
]
}#### SMS Message Fields
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | Yes | Must be "sms" |
| id | string | No | Client-provided message ID |
| sourceAddr | string | No | Sender address (max 15 chars) |
| sourceAddrTon | number | No | Source address TON (0-255) |
| sourceAddrNpi | number | No | Source address NPI (0-255) |
| destAddr | string | Yes | Recipient phone number (max 15 chars) |
| msg | string | Yes | Message content (max 1600 chars) |
| esmClass | number | No | ESM class (0-255) |
| protocolId | number | No | Protocol ID (0-255) |
| priority | number | No | Priority (0-255) |
| sendWhen | string/date | No | Scheduled send time |
| scheduleDeliveryTime | string/date | No | Schedule delivery time |
| validityPeriod | string/date | No | Validity period |
| dataCoding | number | No | Data coding (0-255) |
#### Email Message Fields
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | Yes | Must be "email" |
| sourceAddr | string | Yes | Sender email address |
| sourceAddrName | string | No | Sender name (max 200 chars) |
| destAddr | string | Yes | Recipient email address |
| destAddrName | string | No | Recipient name (max 200 chars) |
| subject | string | Yes | Email subject (max 500 chars) |
| body | string | Yes | Email body (max 1MB) |
| bodyFormat | string | No | "html" or "text" (default: "html") |
| emailProviderId | number | No | Email provider ID (default: 2) |
#### Success Response (200 OK)
{
"status": "success",
"simulationMode": false,
"results": [
{
"id": "optional-client-id",
"type": "sms",
"status": "queued",
"messageId": 123456,
"msgCount": 1
},
{
"type": "email",
"status": "queued",
"emailId": 789
}
],
"summary": {
"total": 2,
"sms": 1,
"email": 1,
"creditsUsed": 1
}
}#### Error Responses
Authentication Error (401)
{
"status": "error",
"error": {
"code": "AUTHENTICATION_FAILED",
"message": "Invalid AccessToken"
}
}Validation Error (400)
{
"status": "error",
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request data",
"details": [...]
}
}Rate Limit Error (429)
{
"status": "error",
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded for SMS. Limit: 6. Current: 6. Try again in 7 seconds.",
"retryAfter": 7,
"details": {
"messageType": "SMS",
"limit": 6,
"currentCount": 6
}
}
}Note: Rate limit responses include a
Retry-After header.Insufficient Credit Error (402)
{
"status": "error",
"error": {
"code": "INSUFFICIENT_CREDIT",
"message": "Insufficient SMS credits. Required: 5, Available: 2",
"details": {
"creditsNeeded": 5,
"creditsAvailable": 2
}
}
}#2. Health Check
Check if the API service is healthy.
Endpoint: GET /health
Authentication: Not required
Response (200 OK):
{
"status": "healthy",
"timestamp": "2025-10-18T12:00:00.000Z",
"environment": "development",
"database": "connected"
}Response (503 Service Unavailable):
{
"status": "unhealthy",
"timestamp": "2025-10-18T12:00:00.000Z",
"environment": "development",
"database": "disconnected",
"error": "Connection timeout"
}#3. Readiness Check
Check if the API service is ready to accept requests.
Endpoint: GET /ready
Authentication: Not required
Response (200 OK):
{
"status": "ready",
"timestamp": "2025-10-18T12:00:00.000Z"
}#4. Get SMS Logs
Retrieve SMS message logs for your system.
Endpoint: GET /api/v1/logs/sms
Authentication: Required
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | number | No | Number of records to return (1-100, default: 50) |
| offset | number | No | Number of records to skip (default: 0) |
| status | string | No | Filter by message status |
| startDate | string | No | Filter by start date (ISO 8601 format) |
| endDate | string | No | Filter by end date (ISO 8601 format) |
Success Response (200 OK):
{
"status": "success",
"data": [
{
"messageId": 10798634,
"destAddr": "4791748750",
"msg": "Test SMS from production API",
"msgCount": 1,
"status": "queued",
"createdAt": "2025-10-18T11:34:15.000Z",
"sendWhen": "2025-10-18T11:34:15.000Z",
"sourceAddr": "1234567890"
}
],
"pagination": {
"total": 150,
"limit": 50,
"offset": 0,
"hasMore": true
}
}#5. Search Companies
Search for Norwegian companies by name or organization number.
Endpoint: GET /api/v1/companies/search
Authentication: Required
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| search | string | Yes | Company name or 9-digit organization number |
Success Response (200 OK):
{
"status": "success",
"companies": [
{
"orgNr": "987654321",
"navn": "Example Company AS",
"forrAdrPostSted": "Oslo"
},
{
"orgNr": "123456789",
"navn": "Another Example AS",
"forrAdrPostSted": "Bergen"
}
]
}Notes:
- If search is exactly 9 numeric digits, searches by organization number
- Otherwise, searches by company name (prefix match)
- Returns maximum 5 results
- Excludes hidden and deleted companies from name searches
#6. Get Company by Organization Number
Get a specific company by its organization number.
Endpoint: GET /api/v1/companies/:orgNr
Authentication: Required
URL Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| orgNr | string | Yes | 9-digit organization number |
Success Response (200 OK):
Returns comprehensive company information with all available fields:
{
"status": "success",
"companies": [
{
"orgnr": 984851006,
"navn": "DNB BANK ASA",
"organisasjonsform": "ASA",
"forretningsadr": "Dronning Eufemias gate 30",
"forradrpostnr": "0191",
"forradrpoststed": "OSLO",
"forradrkommnr": 301,
"forradrkommnavn": "OSLO",
"forradrland": "Norge",
"postadresse": "Postboks 1600 Sentrum",
"ppostnr": "0021",
"ppoststed": "OSLO",
"ppostland": "Norge",
"regifr": true,
"regimva": true,
"nkode1": "64.190",
"nkode2": null,
"nkode3": null,
"sektorkode": 3200,
"konkurs": false,
"avvikling": false,
"tvangsavvikling": false,
"regiaa": false,
"regifriv": false,
"regdato": "2002-09-12T00:00:00.000Z",
"stiftelsesdato": "2002-09-10T00:00:00.000Z",
"tlf": null,
"tlf_mobil": "4791504800",
"url": "www.dnb.no",
"regnskap": 2023,
"hovedenhet": null,
"ansatte_antall": 8343,
"ansatte_dato": "2025-02-12T00:00:00.000Z",
"Slettet": false,
"Hidden": false
}
]
}Field Descriptions:
| Field | Type | Description |
|---|---|---|
| orgnr | number | Organization number |
| navn | string | Company name |
| organisasjonsform | string | Organization form (AS, ASA, etc.) |
| forretningsadr | string | Business address street |
| forradrpostnr | string | Business address postal code |
| forradrpoststed | string | Business address city |
| forradrkommnr | number | Business address municipality number |
| forradrkommnavn | string | Business address municipality name |
| forradrland | string | Business address country |
| postadresse | string | Postal address |
| ppostnr | string | Postal code |
| ppoststed | string | Postal city |
| ppostland | string | Postal country |
| regifr | boolean | Registered in Foretaksregisteret |
| regimva | boolean | Registered for VAT |
| nkode1 | string | Primary industry code (NACE) |
| nkode2 | string | Secondary industry code |
| nkode3 | string | Tertiary industry code |
| sektorkode | number | Sector code |
| konkurs | boolean | In bankruptcy |
| avvikling | boolean | In liquidation |
| tvangsavvikling | boolean | In forced liquidation |
| regiaa | boolean | Registered in Employer Register |
| regifriv | boolean | Registered for voluntary organizations |
| regdato | string | Registration date (ISO 8601) |
| stiftelsesdato | string | Foundation date (ISO 8601) |
| tlf | string | Phone number |
| tlf_mobil | string | Mobile phone |
| url | string | Website URL |
| regnskap | number | Latest accounting year |
| hovedenhet | number | Parent organization number |
| ansatte_antall | number | Number of employees |
| ansatte_dato | string | Employee count date (ISO 8601) |
| Slettet | boolean | Deleted status |
| Hidden | boolean | Hidden status |
Error Response (400 Bad Request):
{
"status": "error",
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid organization number",
"details": [
{
"code": "invalid_string",
"message": "Organization number must be exactly 9 digits",
"path": ["orgNr"]
}
]
}
}#7. Get Email Logs
Retrieve Email message logs for your system.
Endpoint: GET /api/v1/logs/email
Authentication: Required
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| limit | number | No | Number of records to return (1-100, default: 50) |
| offset | number | No | Number of records to skip (default: 0) |
| status | string | No | Filter by message status |
| startDate | string | No | Filter by start date (ISO 8601 format) |
| endDate | string | No | Filter by end date (ISO 8601 format) |
Success Response (200 OK):
{
"status": "success",
"data": [
{
"emailId": 549870,
"sourceAddr": "noreply@sqlexpert.no",
"destAddr": "nilsarne@tvedten.no",
"subject": "Test from Production API",
"status": "queued",
"createdAt": "2025-10-18T11:34:18.000Z",
"bodyFormat": "html"
}
],
"pagination": {
"total": 75,
"limit": 50,
"offset": 0,
"hasMore": true
}
}#Features
#Simulation Mode
When a system is configured with SimulationMode = 1, all messages are stored in simulation tables instead of being sent. This is perfect for testing and development.
To enable simulation mode:
UPDATE CloudCustomer.dbo.APIAccess
SET SimulationMode = 1, Environment = 'Development'
WHERE AccessToken = 'YOUR_ACCESS_TOKEN';Response in simulation mode:
{
"status": "success",
"simulationMode": true,
"results": [
{
"type": "sms",
"status": "simulated",
"messageId": 1,
"msgCount": 1
}
],
"summary": {
"total": 1,
"sms": 1,
"email": 0,
"creditsUsed": 0
}
}#Throttling
The API enforces rate limits based on the system's environment (Development/Production).
Default limits:
| Environment | Type | Per Minute | Per Hour | Per Day |
|---|---|---|---|---|
| Development | SMS | 6 | 60 | 500 |
| Development | 60 | 500 | 5,000 | |
| Production | SMS | 60 | 3,000 | 50,000 |
| Production | 300 | 10,000 | 100,000 |
To customize limits for a specific system:
INSERT INTO CloudCustomer.dbo.MessageThrottleConfig
(SystemID, MessageType, Environment, MaxPerMinute, MaxPerHour, MaxPerDay, Enabled)
VALUES
(123, 'SMS', 'Development', 10, 100, 1000, 1);#cURL Examples
#Send SMS (Production)
curl -X POST https://apiaccess.digify.no/api/v1/messages/send?AccessToken=YOUR_ACCESS_TOKEN \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"type": "sms",
"destAddr": "4712345678",
"msg": "Hello from API!"
}
]
}'#Send Email
curl -X POST https://apiaccess.digify.no/api/v1/messages/send?AccessToken=YOUR_ACCESS_TOKEN \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"type": "email",
"sourceAddr": "noreply@example.com",
"destAddr": "user@example.com",
"subject": "Test Email",
"body": "<h1>Hello!</h1>"
}
]
}'#Send Both SMS and Email
curl -X POST https://apiaccess.digify.no/api/v1/messages/send?AccessToken=YOUR_ACCESS_TOKEN \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"type": "sms",
"destAddr": "4712345678",
"msg": "Hello via SMS!"
},
{
"type": "email",
"sourceAddr": "noreply@example.com",
"destAddr": "user@example.com",
"subject": "Hello",
"body": "Hello via Email!"
}
]
}'#Get SMS Logs
# Get latest 50 SMS messages
curl https://apiaccess.digify.no/api/v1/logs/sms?AccessToken=YOUR_ACCESS_TOKENGet 10 SMS messages with pagination
curl https://apiaccess.digify.no/api/v1/logs/sms?AccessToken=YOUR_ACCESS_TOKEN&limit=10&offset=0Filter by date range
curl "https://apiaccess.digify.no/api/v1/logs/sms?AccessToken=YOUR_ACCESS_TOKEN&startDate=2025-10-01&endDate=2025-10-18"#Get Email Logs
# Get latest 50 email messages
curl https://apiaccess.digify.no/api/v1/logs/email?AccessToken=YOUR_ACCESS_TOKENGet 10 email messages with pagination
curl https://apiaccess.digify.no/api/v1/logs/email?AccessToken=YOUR_ACCESS_TOKEN&limit=10&offset=0Filter by date range
curl "https://apiaccess.digify.no/api/v1/logs/email?AccessToken=YOUR_ACCESS_TOKEN&startDate=2025-10-01&endDate=2025-10-18"#Search Companies
# Search by company name
curl "https://apiaccess.digify.no/api/v1/companies/search?search=Acme&AccessToken=YOUR_ACCESS_TOKEN"Search by organization number (9 digits)
curl "https://apiaccess.digify.no/api/v1/companies/search?search=987654321&AccessToken=YOUR_ACCESS_TOKEN"#Get Company by Organization Number
curl https://apiaccess.digify.no/api/v1/companies/987654321?AccessToken=YOUR_ACCESS_TOKEN#Health Check
curl https://apiaccess.digify.no/health#Error Codes
| Code | HTTP Status | Description |
|---|---|---|
| AUTHENTICATION_FAILED | 401 | Invalid or missing AccessToken |
| VALIDATION_ERROR | 400 | Invalid request data |
| RATE_LIMIT_EXCEEDED | 429 | Too many requests |
| INSUFFICIENT_CREDIT | 402 | Not enough SMS credits |
| DATABASE_ERROR | 500 | Database operation failed |
| INTERNAL_SERVER_ERROR | 500 | Unexpected server error |
| NOT_FOUND | 404 | Endpoint not found |
#Rate Limit Headers
When rate limiting is triggered, the response includes:
- Retry-After: Number of seconds to wait before retrying
#Best Practices
1. Batch Messages: Send multiple messages in one request to reduce overhead
2. Handle Rate Limits: Implement exponential backoff when receiving 429 responses
3. Use Simulation Mode: Test your integration in simulation mode first
4. Monitor Credits: Check credit balance regularly to avoid 402 errors
5. Error Handling: Always check the status field in responses
#Support
For issues or questions:
- Check logs at ./logs/messaging-api.log
- Review database tables: MessageThrottleLog, MessagingAPILog
- Contact support with your SystemID for assistance