idekavan-sms

n8n community nodes for the Idekavan SMS (Arad) API: send SMS, pattern and OTP messages, schedule sends, poll delivery reports and inbound messages, and receive delivery/inbound webhooks.

Package Information

Released: this month
Downloads: 0 weekly / 0 monthly
Latest Version: 0.1.0
Author: idekavan Software Engineers

Documentation

@idekavan/n8n-nodes-idekavan-sms

n8n community nodes for the Idekavan SMS API (the Arad platform at https://api.m.idekavan.com).

Node What it does
Idekavan SMS Send single, bulk, multi-message, pattern, OTP and scheduled SMS; poll delivery reports and inbound messages; read account info
Idekavan SMS Trigger Start a workflow when Idekavan pushes delivery reports or inbound messages to a webhook

Both nodes use one credential type, Idekavan SMS API.

Installation

In n8n, open Settings > Community Nodes, choose Install, enter @idekavan/n8n-nodes-idekavan-sms and confirm. On a self-hosted instance without the UI option, install it in n8n's nodes folder instead and restart n8n:

cd ~/.n8n/nodes && npm install @idekavan/n8n-nodes-idekavan-sms

Develop or try a local build

npm install
npm run build

npm run dev builds in watch mode, links the package into ~/.n8n-node-cli/.n8n/custom, and starts n8n at http://localhost:5678. Changes are rebuilt and reloaded automatically.

It runs npx n8n@latest, and current n8n releases require Node.js 24 or newer. The package itself builds and lints with Node 22.

To link a local build into an n8n you already run, place it in the custom/node_modules folder of n8n's user folder (~/.n8n by default) and restart n8n:

mkdir -p ~/.n8n/custom/node_modules/@idekavan
ln -s "$(pwd)" ~/.n8n/custom/node_modules/@idekavan/n8n-nodes-idekavan-sms

Nodes loaded this way appear with the CUSTOM. type prefix (CUSTOM.idekavanSms). With Docker, mount this folder at /home/node/.n8n/custom/node_modules/@idekavan/n8n-nodes-idekavan-sms instead of creating the link.

Credentials

Create an Idekavan SMS API credential.

Field Default Notes
Base URL https://api.m.idekavan.com
Authentication API Key See the modes below
API Key From the Idekavan dashboard (API Key mode)
Username / Password Your Idekavan login (Bearer Token and Basic Auth modes)
Scope ApiAccess Sent in the Scope header, and requested for the token in Bearer mode
Webhook Username / Password Only used by the trigger, see Idekavan SMS Trigger

Authentication modes:

Mode What is sent
API Key (recommended) X-API-Key: <key>
Bearer Token The credential exchanges the username and password for a token at POST /connect/token and sends Authorization: Bearer <token>. The token is stored on the credential and reused across executions. When Idekavan answers 401, n8n fetches a new token once and retries.
Basic Auth Authorization: Basic base64(username:password). Idekavan does not recommend it.

Things to know before the first call:

  • Register your IP address. Idekavan only accepts calls from IP addresses registered with them in writing; other callers get error -18. The Account > Check IP operation shows the address Idekavan sees.
  • Scopes. Every request carries a Scope header. It is the credential's scope, unless the operation has its own default or you set Options > Scope.
    • Operations with their own default: Send Many (BulkApiAccess) and the Scheduled Message operations (MessageRequestAccess).
    • In API Key and Basic Auth modes, the header is all that is needed.
    • In Bearer mode, the token carries the credential's scope and the header does not change it. Idekavan documents that scheduled messages need a token requested with MessageRequestAccess, and that such a token cannot be used for other sends. Use a Bearer credential with scope MessageRequestAccess for scheduled messages. Send Many is likely to need one with BulkApiAccess, the scope production clients use for it. API Key mode avoids this.
  • Only one token at a time. Idekavan invalidates earlier tokens whenever a new one is issued.
    • Within one n8n process, items that run together share one token request: a first run, or a burst of items whose token expired, fetches a single new token.
    • Separate processes (queue-mode workers, several n8n instances) and Bearer credentials with the same username each fetch their own tokens. Every fetch invalidates the others' tokens, so the next call from the other side gets a 401 and fetches again. That costs extra token requests but does not fail executions.
    • When one account is used from several workers or with several scopes, prefer API Key mode.

Credential test: saving the credential calls GET /api/user/UserInfo. The test fails on an HTTP error or when the response has succeeded: false.

Idekavan SMS operations

Message operations use API version 4 (/api/4/...). That version returns the message ID, the number of parts and the operator for every message. Pattern, OTP and Scheduled Message use the only paths the API offers for them.

Message

Operation Endpoint Description
Send POST /api/4/message/send One SMS per input item
Send Bulk POST /api/4/message/bulk One text from one sender to many recipients
Send Many POST /api/4/message/P2PBulk A list of individual messages in one request
Get Delivery Status POST /api/4/message/GetDLR Poll delivery reports for up to 1000 message IDs
Get Inbound Messages GET /api/4/message/GetMO Up to 1000 unread messages sent to your numbers
Get Inbound Messages by Date GET /api/4/message/GetMOByDate Inbound messages between two times

Send fields: Source Address (a sender number assigned to your account), Destination Address, Message Text.

Options (each maps to the API field with the same name):

Option API field Notes
Data Coding dataCoding Default Auto-Detect: GSM-7 (8) when every character fits the GSM alphabet, otherwise UCS-2 (1). Also: GSM-7, UCS-2, or Server Default (omit the field).
Validity Period validityPeriod Must be 1 to 6 hours from now; arrange with Idekavan before using it
Target UDH targetUDH referenceNumberType:16bit or referenceNumberType:8bit
UDH udh Your own ID for the message (Idekavan suggests a UUID); returned by Get Delivery Status with Return UDH
Priority priority 0–7
Message Class messageClass 0–13
Service ID serviceID
Return Long ID returnLongId query parameter Numeric IDs instead of 24-character UIDs; see message IDs
Return Part ID returnPartId query parameter
Scope Scope header Overrides the scope for this request

Send output, one item per message:

{ "id": "6753fea42e0d853017a20ba8", "part": "1", "upstreamGateway": "MCI", "destinationAddress": "+989121234567", "accepted": true }

Send Bulk fields: Source Address, Destination Addresses (separated by commas, semicolons or new lines, or an array from an expression), Message Text.

  • Options: Validity Period, Target UDH, UDH, Service ID, Service Price, Return Long ID, Scope.
  • The bulk endpoint has no data coding, priority or message class.
  • Output: one item per recipient.

Send Many combines many individual messages into one request.

  • Messages is a JSON array, or an expression that returns one, of objects with the AradA2PMessage properties:
    • destinationAddress and messageText are required;
    • sourceAddress, dataCoding, validityPeriod, targetUDH, serviceID, priority, messageClass and udh are optional.
  • Default Source Address fills in messages without a sourceAddress.
  • Options > Data Coding applies to messages without their own dataCoding.
  • The request uses scope BulkApiAccess by default, the scope production clients use for this endpoint.

To send one message per input item in a single request, first combine the items with the Aggregate node, then map the list into Messages, for example:

{{ $json.data.map(row => ({ destinationAddress: row.phone, messageText: `Hi ${row.name}` })) }}

Get Delivery Status

  • Message IDs: IDs from a send, separated by commas, spaces or new lines, or an array. The array can also hold send results, whose id is used. At most 1000 per request.
  • Options:
    • Return Long ID must match the send.
    • Return UDH and Return Sent Date add those fields.
  • Idekavan only serves delivery reports when the account's delivery-report setting is Pull.
  • Output: one item per message, with deliveryStatusName and a readable parts list added:
{
  "id": "624ed1bbcd0efb1ef148e0a0",
  "deliveryStatus": 34,
  "deliveryStatusName": "Undeliverable",
  "partStatus": [{ "item1": 1, "item2": 34, "item3": "2022-04-07T11:57:50.044Z" }],
  "parts": [{ "partNumber": 1, "status": 34, "statusName": "Undeliverable", "receivedAt": "2022-04-07T11:57:50.044Z" }]
}

Idekavan converts a multipart message to Enroute (33) 20 minutes after its last report when:

  • the overall status is Delivered, and
  • some parts are delivered while the rest are undeliverable or expired.

Poll such messages again at least 20 minutes later.

Get Inbound Messages returns up to 1000 unread messages as {sourceAddress, destinationAddress, messageText, receiveDateTime} items. When there are no messages, Idekavan answers 404 with code 109; the node returns no items instead of failing. This endpoint does not work when inbound messages are pushed to a webhook; Get Inbound Messages by Date does.

Get Inbound Messages by Date takes Start Date Time and End Date Time (the startDateTime/endDateTime query parameters). Option Return ID adds a unique ID per message.

Pattern

Operation Endpoint
Send POST /api/patternMessage/send
  • Pattern ID is the ID of a pattern defined and approved in the Idekavan dashboard.
  • Destinations are one or more numbers; one message is created per number.
  • Parameters are the placeholder values in order: the first fills {0}, the second {1}, and so on.
  • Options: Return Long ID, Scope.

OTP

Operation Endpoint
Send POST /api/1/Otp/SendOtp

It takes the same fields and options as Message > Send.

The endpoint comes from the Idekavan Swagger but is not described in the customer document, so its exact behaviour (compared with a normal send) and the scope it needs are not documented.

Scheduled Message

All scheduled-message operations send Scope: MessageRequestAccess unless Options > Scope says otherwise.

Operation Endpoint Description
Create POST /api/1/Schedule/SendOnce Schedule one text to up to 100 recipients at Due Date. Output: { messageRequestId }
Approve GET /api/1/Schedule/ApproveMessage Approve a request waiting for approval, by Message Request ID
Get Waiting Approval GET /api/1/Schedule/GetWaitingApprove List requests waiting for approval
  • Campaign Name (optional) must be unique; Idekavan suggests a UUID.
  • After submission a request can only be viewed or deleted in the Idekavan panel.

Account

Operation Endpoint Output
Get Info GET /api/user/UserInfo userName, firstName, lastName, credit, mps (messages per second), senderIds
Check IP GET /api/Tools/CheckIp { "ip": "…" }, the address Idekavan sees

Endpoints not covered

The Swagger also contains PhoneBook, SmartSms, periodic and gradual schedules, reports, live data, KYC, tickets, WebEngage, SendBySpecialParameter, SendToWhiteList, CreateCampaign and GetDLRByPartId. Their behaviour is undocumented, or they look like operator-only endpoints.

To call them, use n8n's HTTP Request node:

  1. Set Authentication to Predefined Credential Type.
  2. Set Credential Type to Idekavan SMS API.
  3. Enter the full URL.

The credential adds the same headers there, including the token refresh.

Idekavan SMS Trigger

Idekavan has no API for registering webhooks, so set it up like this:

  1. Add the trigger and choose the Event:
    • Any: each item gets eventType deliveryReport or inboundMessage;
    • Delivery Report;
    • Inbound Message.
  2. Choose the HTTP Method Idekavan will use: POST for their JSON pushes, GET if you asked for query-string pushes.
  3. Optionally set Authentication to Basic Auth, and enter a Webhook Username and Webhook Password on an Idekavan SMS API credential.
  4. Activate the workflow and send the Production URL to Idekavan support. Say which events it should receive, which method to use, and the username and password if you set them.

What the trigger does with each push:

  • Payload formats. It accepts a JSON array (how delivery reports are pushed), a single JSON object (how inbound messages are pushed), form fields, or query parameters.
  • One item per event. Keys are kept exactly as Idekavan sends them.
  • Status fields. Delivery reports also get statusCode and statusName.
  • Unrecognised shapes are passed on with eventType: "unknown", never dropped.
  • Response. It answers {"status":"accepted","events":N} immediately, and 401 when Basic Auth is enabled and the credentials don't match.
  • Ignored pushes. If nothing in a push matches the selected Event, or the push is empty, it answers HTTP 200 {"status":"ignored"} and does not start the workflow. Because the push is acknowledged, it will not be retried if Idekavan only retries failed pushes; their retry policy is undocumented. If one URL receives both types, choose Any.

A delivery report item (PDF example):

{
  "eventType": "deliveryReport",
  "Status": "Delivered",
  "PartNumber": "1",
  "MessageId": "6a772a156d730d57be53bd2e",
  "DateTime": "8/8/2026 1:07:36 PM",
  "Mobile": "989121234567",
  "FullDelivery": true,
  "ErrorCode": "000",
  "statusCode": 1,
  "statusName": "Delivered"
}

Errors

The node never assumes a call worked just because the HTTP status is 2xx. It succeeds only when:

  • the HTTP status is 2xx, and
  • the response envelope has resultCode: 100 and succeeded is not false.

Other outcomes become an n8n error:

Situation Error
Envelope with another result code (any HTTP status) Idekavan SMS error <code>: <meaning>, for example Idekavan SMS error 118: Rate limit exceeded. The description quotes Idekavan's message, the HTTP status, and a hint (IP registration, credit, rate limit, sender number…).
Non-JSON error response Idekavan SMS request failed with HTTP status <status>
2xx response without Idekavan's envelope, for example an empty body, a proxy's HTML page or a gateway's JSON (not applied to Check IP, which answers in plain text) Idekavan SMS returned an unexpected response (HTTP status <status>)
HTTP 401 n8n's own "Authorization failed" error, after one token refresh in Bearer mode
Invalid input (bad phone number, empty text, more than 1000 IDs…) Raised before that item's request is sent

The meanings come from the code tables in the Idekavan API document: send errors 0 to −43 and result codes 100–137.

Rejected recipients. Idekavan can accept a request but reject individual recipients. The rejected recipient's ID is then replaced by a send error code, for example -12 for an invalid recipient.

  • When every recipient of an item is rejected (always the case for a single Send), nothing was sent for that item, and the item fails with the reason.
  • When only some are rejected, the item does not fail. Each recipient becomes its own output item with accepted, and rejected ones also get errorCode and errorMessage. Filter on accepted to handle them.

This is deliberate: failing the item would invite a retry that re-sends the messages that were accepted.

Several items. n8n sends all input items before it looks at any failure. If one item fails, because of invalid input or because all its recipients were rejected, the other items' messages have already been sent. Without further settings, the node then reports only the error and drops their message IDs, and re-running the execution sends them again. For sends with more than one item, set Settings > On Error to Continue (using error output): accepted items keep their message IDs and only the failed items go to the error output.

Retries. Do not enable Retry On Fail on send operations. A request that timed out or failed on the server may already have been accepted, and repeating it can deliver the SMS twice. Check delivery reports first.

Behaviour notes and limitations

  • Phone numbers. Destinations must be Iranian mobile numbers.
    • Accepted forms: 09…, 9…, 98…, +98…, 0098…, 098…, Persian and Arabic-Indic digits, spaces, dashes and brackets.
    • Lists may be separated by commas, semicolons (including the Persian ، and ؛) or new lines.
    • They are sent as +989XXXXXXXXX, the form production clients use.
    • Anything else fails that item before it is sent.
    • Source addresses are sent as entered.
  • Data coding. Idekavan's API document says Persian is 8 and English is 1. The production clients (the idk-messaging SDK and dobare) send the reverse: 1 for UCS-2/Persian and 8 for GSM-7. This node follows production. Choose Server Default to leave the choice to Idekavan.
  • Message IDs.
    • By default IDs are 24-character hex UIDs.
    • With Return Long ID they are 19-digit numbers. These are larger than JavaScript can represent exactly, so keep them as strings.
    • Get Delivery Status rejects numeric IDs that have already lost precision.
    • Use the same Return Long ID setting for a send and its delivery-status lookup.
  • Request limits. There is no pagination anywhere in the API. Idekavan documents these limits:
    • 1000 IDs per delivery-status request;
    • 1000 inbound messages per call;
    • 100 recipients per scheduled message.
      Other batch sizes are not documented.
  • Dates. Dates are sent as wall-clock time without an offset, to the second (2030-01-01T09:00:00), matching Idekavan's examples.
    • Values from the date picker are sent as they are.
    • Date expressions (Luxon DateTimes such as {{ $now.plus({ hours: 2 }) }}, JavaScript Dates, and ISO text with an offset or Z) are first converted to the workflow's time zone. The same instant is therefore always sent as the same text.
    • An invalid date fails the item.
    • It is not documented whether Idekavan reads offset-less times as UTC or Tehran time. Set the workflow time zone to the one Idekavan expects (most likely Asia/Tehran).
  • Redirects. Credentials are not forwarded on cross-origin redirects.
  • Extra 401 request. In API Key and Basic Auth modes, n8n repeats a request that got 401 once, because the credential supports token refresh. Both requests are rejected, so nothing is sent twice.

Development

npm install
npm run build      # compile to dist/
npm run lint       # n8n community-node lint rules (strict)
npm test           # build, then run the unit tests in test/ with node:test
npm run dev        # n8n with hot reload (needs Node.js 24+)

To publish a new version, bump version in package.json, update CHANGELOG.md, tag the commit vX.Y.Z, and run RELEASE_MODE=true npm publish --access public. The starter's npm run release expects GitHub and is not used here.

credentials/IdekavanSmsApi.credentials.ts   credential, token handling, credential test
nodes/IdekavanSms/
  IdekavanSms.node.ts                       declarative node (no execute())
  resources/<resource>/                     operations and their fields
  shared/                                   request builders, response hooks, error mapping, code tables
nodes/IdekavanSmsTrigger/                   webhook trigger and payload parsing
test/                                       unit tests against dist/

The action node is fully declarative. Request bodies are built in preSend hooks and responses are checked in postReceive hooks.

Its requestDefaults use ignoreHttpStatusErrors: { ignore: true, except: [401] }, which does two things:

  • error responses reach the hooks, so they can be mapped to Idekavan's codes;
  • a 401 still throws, so n8n can refresh a bearer token.

Verified with: @n8n/node-cli 0.49.1, n8n-workflow 2.40.1, and n8n 2.40.5.

Discussion