Skip to Content
Welcome to Zendera Knowledge Hub
API DocumentationNotifications Log

Notifications Log API

Retrieve and search through email and SMS notification logs sent by the Zendera platform. Useful for tracking delivery status, debugging notification issues, and auditing communication history.

Authentication

Authorization: apikey YOUR_API_KEY_HERE

Base URLs

  • Production: https://app.zenderatms.com/api/
  • Staging: https://staging.zenderatms.com/api/

Interactive API Explorer

Loading API Documentation...

Available Endpoints

1. Search Order Notifications (Combined)

Retrieve all notifications (both email and SMS) for a specific order.

Endpoint: POST /v1/order-notifications-log

Use Case: Get a complete communication history for an order, useful for customer service and tracking.

Request Body

{ "orderId": 12345, // Required: The order ID to search for "receiver": "john@email.com", // Optional: Filter by email or phone number "isAsc": false, // Optional: Sort order (default: false = newest first) "page": 1, // Required: Page number (1-based) "perPage": 50 // Required: Records per page (max recommended: 100) }

Response

{ "records": [ { "id": 1001, "type": "EMAIL", // EMAIL or SMS "createdAt": "2024-01-15T10:30:00Z", "orderId": 12345, "receiver": "john@email.com", "email": { // Present when type = EMAIL "emailLogId": 2001, "orgId": 100, "orderId": 12345, "orderLocationId": 5001, "contactId": 3001, "emailType": "order_confirmation", "fromAddress": "noreply@zendera.com", "toAddress": "john@email.com", "subject": "Order #12345 Confirmed", "body": "Your order has been confirmed...", "bodyHtml": "<html>Your order has been confirmed...</html>", "provider": "sendgrid", "status": "delivered", "createdAt": "2024-01-15T10:30:00Z", "deliveredAt": "2024-01-15T10:30:15Z" } }, { "id": 1002, "type": "SMS", "createdAt": "2024-01-15T11:00:00Z", "orderId": 12345, "receiver": "+47123456789", "sms": { // Present when type = SMS "smsLogId": 3001, "orgId": 100, "orderId": 12345, "orderLocationId": 5001, "trackTraceCode": "TT123456", "event": "out_for_delivery", "message": "Your package is out for delivery", "toNumber": "+47123456789", "fromNumber": "+4712345678", "providerName": "sms_provider", "status": "sent", "createdAt": "2024-01-15T11:00:00Z", "updatedAt": "2024-01-15T11:00:05Z", "sentAt": "2024-01-15T11:00:03Z", "dequeuedAt": "2024-01-15T11:00:01Z" } } ], "totalRecords": 25, "numPages": 1, "pageNum": 1, "perPage": 50 }

2. Search Email Logs

Search specifically for email notification logs.

Endpoint: POST /v1/notifications-log/emails

Use Case: Track email delivery status, debug email issues, or audit email communications.

Request Body

{ "orderId": 12345, // Optional: Filter by order ID (0 = records not tied to orders) "receiverEmail": "john@email.com", // Optional: Filter by recipient email (partial match supported) "isAsc": false, // Optional: Sort order (default: false = newest first) "page": 1, // Required: Page number (1-based) "perPage": 50 // Required: Records per page }

Response

{ "emailLogs": [ { "emailLogId": 2001, "orgId": 100, "orderId": 12345, "orderLocationId": 5001, "contactId": 3001, "eventId": 4001, "notificationConfigurationId": 6001, "emailType": "order_confirmation", "fromAddress": "noreply@zendera.com", "toAddress": "john@email.com", "subject": "Order #12345 Confirmed", "body": "Your order has been confirmed and is being processed...", "bodyHtml": "<html><body>Your order has been confirmed...</body></html>", "provider": "sendgrid", "status": "delivered", "createdAt": "2024-01-15T10:30:00Z", "deliveredAt": "2024-01-15T10:30:15Z" } ], "totalRecords": 10, "numPages": 1, "pageNum": 1, "perPage": 50 }

3. Search SMS Logs

Search specifically for SMS notification logs.

Endpoint: POST /v1/notifications-log/sms

Use Case: Track SMS delivery status, monitor SMS costs, or debug SMS delivery issues.

Request Body

{ "orderId": 12345, // Optional: Filter by order ID (0 = records not tied to orders) "toNumber": "+47123", // Optional: Filter by phone number (partial match supported) "isAsc": false, // Optional: Sort order (default: false = newest first) "page": 1, // Required: Page number (1-based) "perPage": 50 // Required: Records per page }

Response

{ "smsLogs": [ { "smsLogId": 3001, "orgId": 100, "orderId": 12345, "orderLocationId": 5001, "trackTraceCode": "TT123456", "event": "out_for_delivery", "message": "Your package is out for delivery. Track: TT123456", "toNumber": "+47123456789", "fromNumber": "+4712345678", "providerName": "smsteknik", "sendWindowFrom": "2024-01-15T08:00:00Z", "sendWindowTo": "2024-01-15T20:00:00Z", "status": "sent", "createdAt": "2024-01-15T11:00:00Z", "updatedAt": "2024-01-15T11:00:05Z", "sentAt": "2024-01-15T11:00:03Z", "dequeuedAt": "2024-01-15T11:00:01Z" } ], "totalRecords": 15, "numPages": 1, "pageNum": 1, "perPage": 50 }

Field Reference

Response Field Descriptions

Root Record Fields

FieldTypeDescription
idintegerUnique notification record ID
typeenumNotification type: EMAIL or SMS
createdAtstring (ISO 8601)When the notification was created
orderIdintegerAssociated order ID
receiverstringRecipient email address or phone number
emailobjectEmail details (present when type = EMAIL)
smsobjectSMS details (present when type = SMS)

Email Object Fields

FieldTypeDescription
emailLogIdintegerUnique email log identifier
orgIdintegerOrganization ID
emailTypestringEmail template type (e.g., “order_confirmation”)
fromAddressstringSender email address
toAddressstringRecipient email address
subjectstringEmail subject line
bodystringPlain text email content
bodyHtmlstringHTML email content
providerstringEmail service provider (e.g., “sendgrid”)
statusenumEmail delivery status (see Email Status Values below)
deliveredAtstring (ISO 8601)When email was delivered (if applicable)

SMS Object Fields

FieldTypeDescription
smsLogIdintegerUnique SMS log identifier
orgIdintegerOrganization ID
trackTraceCodestringOrder tracking code
eventstringTriggering event (e.g., “out_for_delivery”)
messagestringSMS message content
toNumberstringRecipient phone number
fromNumberstringSender phone number
providerNamestringSMS service provider (e.g., “sms_provider”)
sendWindowFromstring (ISO 8601)Earliest send time
sendWindowTostring (ISO 8601)Latest send time
statusenumSMS delivery status (see SMS Status Values below)
sentAtstring (ISO 8601)When SMS was sent (if applicable)
dequeuedAtstring (ISO 8601)When SMS was picked up for processing

Status Field Documentation

Understanding notification status values is crucial for tracking delivery success and debugging issues.

Status Values Quick Reference

Email Status Enum

enum EmailStatus { queued, // Email queued for sending sent, // Handed off to email provider delivered, // Successfully delivered to recipient server failed, // Permanent delivery failure bounced, // Rejected by recipient server spam // Delivered but marked as spam }

SMS Status Enum

enum SMSStatus { queued, // SMS queued for sending job_dequeued, // Picked up for processing (legacy API naming) sent, // Handed off to SMS provider delivered, // Successfully delivered to device failed // Permanent sending failure }

Note: The job_dequeued status follows the original API naming convention for backward compatibility. While typical enum naming would use JOB_DEQUEUED or jobDequeued, this value matches the actual API response format.

Email Status Values

  • queued - Email is queued for sending

    • When it occurs: Initial status when email is created and added to the sending queue
    • Next expected status: sent or failed
    • Troubleshooting: If stuck in queued, check email provider limits or system capacity
  • sent - Email has been sent to email provider

    • When it occurs: Email successfully handed off to email service provider (SendGrid, etc.)
    • Next expected status: delivered, bounced, or spam
    • Note: This doesn’t guarantee delivery to recipient’s inbox
  • delivered - Email was successfully delivered to recipient’s email server

    • When it occurs: Email provider confirms successful delivery to destination server
    • Final status: Yes - indicates successful delivery
    • Note: Delivery to server doesn’t guarantee inbox placement
  • failed - Email delivery failed permanently

    • When it occurs: Email couldn’t be sent due to system errors, invalid configuration, or provider issues
    • Final status: Yes - requires manual intervention
    • Common causes: Invalid API keys, malformed email addresses, provider outages
  • bounced - Email bounced back from recipient’s server

    • When it occurs: Recipient’s email server rejected the email
    • Final status: Yes - permanent delivery failure
    • Common causes: Invalid email addresses, full mailboxes, recipient server blocking
  • spam - Email marked as spam by recipient’s server or filters

    • When it occurs: Email delivered but flagged as spam by recipient’s email system
    • Final status: Yes - delivered but may not reach inbox
    • Impact: Can affect sender reputation and future deliverability

SMS Status Values

  • queued - SMS is queued for sending

    • When it occurs: Initial status when SMS is created and added to the sending queue
    • Next expected status: job_dequeued, sent, or failed
    • Troubleshooting: If stuck in queued, check SMS provider limits or system capacity
  • job_dequeued - SMS job has been picked up for processing

    • When it occurs: SMS has been removed from queue and is being processed by the sending system
    • Next expected status: sent or failed
    • Duration: Usually brief - indicates active processing
  • sent - SMS has been sent to SMS provider

    • When it occurs: SMS successfully handed off to SMS service provider
    • Next expected status: delivered or remains sent if delivery confirmation unavailable
    • Note: Provider-dependent whether delivery confirmations are supported
  • delivered - SMS was successfully delivered to recipient’s device

    • When it occurs: SMS provider confirms successful delivery to recipient’s mobile device
    • Final status: Yes - indicates successful delivery
    • Availability: Depends on SMS provider and recipient’s carrier support
  • failed - SMS sending failed permanently

    • When it occurs: SMS couldn’t be sent due to system errors, invalid phone numbers, or provider issues
    • Final status: Yes - requires manual intervention
    • Common causes: Invalid phone numbers, insufficient credits, provider outages, blocked numbers

Status Workflow Examples

Successful Email Flow: queuedsentdelivered

Failed Email Flow: queuedfailed (system error) queuedsentbounced (recipient error)

Successful SMS Flow: queuedjob_dequeuedsentdelivered

Failed SMS Flow: queuedfailed (invalid number) queuedjob_dequeuedsent (no delivery confirmation available)

Status Field Usage Examples

Filtering by Status

// Filter only successfully delivered emails const deliveredEmails = notifications.records.filter(record => record.type === 'EMAIL' && record.email.status === 'delivered' ); // Find failed notifications for retry const failedNotifications = notifications.records.filter(record => { if (record.type === 'EMAIL') { return ['failed', 'bounced'].includes(record.email.status); } if (record.type === 'SMS') { return record.sms.status === 'failed'; } });

Status-based Analytics

// Count notifications by status function analyzeNotificationStatus(records) { const stats = { email: { queued: 0, sent: 0, delivered: 0, failed: 0, bounced: 0, spam: 0 }, sms: { queued: 0, job_dequeued: 0, sent: 0, delivered: 0, failed: 0 } }; records.forEach(record => { if (record.type === 'EMAIL') { stats.email[record.email.status]++; } else if (record.type === 'SMS') { stats.sms[record.sms.status]++; } }); return stats; }

Status Validation

// TypeScript enum definitions for validation enum EmailStatus { QUEUED = 'queued', SENT = 'sent', DELIVERED = 'delivered', FAILED = 'failed', BOUNCED = 'bounced', SPAM = 'spam' } enum SMSStatus { QUEUED = 'queued', JOB_DEQUEUED = 'job_dequeued', SENT = 'sent', DELIVERED = 'delivered', FAILED = 'failed' } // Validate status values function isValidEmailStatus(status: string): status is EmailStatus { return Object.values(EmailStatus).includes(status as EmailStatus); } function isValidSMSStatus(status: string): status is SMSStatus { return Object.values(SMSStatus).includes(status as SMSStatus); }

Example Usage

Curl Examples

Search all notifications for an order:

curl -X POST "https://app.zenderatms.com/api/v1/order-notifications-log" \ -H "Authorization: apikey YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "orderId": 12345, "page": 1, "perPage": 50 }'

Search email logs by recipient:

curl -X POST "https://app.zenderatms.com/api/v1/notifications-log/emails" \ -H "Authorization: apikey YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "receiverEmail": "customer@example.com", "page": 1, "perPage": 20 }'

Search SMS logs for specific phone number:

curl -X POST "https://app.zenderatms.com/api/v1/notifications-log/sms" \ -H "Authorization: apikey YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "toNumber": "+47123456789", "page": 1, "perPage": 20 }'

JavaScript/Node.js Example

const axios = require('axios'); async function getOrderNotifications(orderId) { try { const response = await axios.post( 'https://app.zenderatms.com/api/v1/order-notifications-log', { orderId: orderId, page: 1, perPage: 50 }, { headers: { 'Authorization': 'apikey YOUR_API_KEY', 'Content-Type': 'application/json' } } ); console.log(`Found ${response.data.totalRecords} notifications for order ${orderId}`); return response.data.records; } catch (error) { console.error('Error fetching notifications:', error.response?.data || error.message); } } // Usage getOrderNotifications(12345);

Python Example

import requests def search_email_logs(receiver_email=None, order_id=None, page=1, per_page=50): url = "https://app.zenderatms.com/api/v1/notifications-log/emails" headers = { "Authorization": "apikey YOUR_API_KEY", "Content-Type": "application/json" } payload = { "page": page, "perPage": per_page } if receiver_email: payload["receiverEmail"] = receiver_email if order_id: payload["orderId"] = order_id response = requests.post(url, json=payload, headers=headers) if response.status_code == 200: data = response.json() print(f"Found {data['totalRecords']} email logs") return data["emailLogs"] else: print(f"Error: {response.status_code} - {response.text}") return None # Usage email_logs = search_email_logs(receiver_email="customer@example.com")

Error Handling

The API returns standard HTTP status codes:

  • 200 - Success
  • 400 - Bad Request (invalid parameters)
  • 401 - Unauthorized (invalid or missing API key)
  • 500 - Internal Server Error

Error responses follow this format:

{ "code": 3, "message": "invalid argument: order_id is required", "details": [] }

Rate Limiting

Please be mindful of API rate limits. For high-volume operations, implement appropriate retry logic with exponential backoff.

Best Practices

  1. Pagination: Always use pagination for large result sets. Start with reasonable page sizes (50-100 records).

  2. Filtering: Use specific filters (orderId, receiverEmail, toNumber) to reduce response size and improve performance.

  3. Date-based Queries: For historical data analysis, consider implementing date range filtering in your application logic.

  4. Error Handling: Always handle authentication errors and implement retry logic for transient failures.

  5. Caching: Consider caching results for frequently accessed data to reduce API calls.

Troubleshooting

Common Issues

No results returned:

  • Verify the orderId exists and belongs to your organization
  • Check if the order has any notifications configured
  • Ensure you’re using the correct authentication credentials

Authentication errors:

  • Verify your API key is valid and active
  • Check that your API key has the necessary permissions
  • Ensure the Authorization header format is correct

Empty notification logs:

  • Orders may not have notifications if they were created before notification features were enabled
  • Check notification configuration for the specific order type
  • Verify that customer contact information (email/phone) was provided

Support

For additional support, contact the Zendera API team with your specific use case and any error messages.

Last updated on