Package Information
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
- Credentials
- Idekavan SMS operations
- Idekavan SMS Trigger
- Errors
- Behaviour notes and limitations
- Development
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
Scopeheader. 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 scopeMessageRequestAccessfor scheduled messages. Send Many is likely to need one withBulkApiAccess, the scope production clients use for it. API Key mode avoids this.
- Operations with their own default: Send Many (
- 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
AradA2PMessageproperties:destinationAddressandmessageTextare required;sourceAddress,dataCoding,validityPeriod,targetUDH,serviceID,priority,messageClassandudhare optional.
- Default Source Address fills in messages without a
sourceAddress. - Options > Data Coding applies to messages without their own
dataCoding. - The request uses scope
BulkApiAccessby 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
idis 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
deliveryStatusNameand a readablepartslist 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:
- Set Authentication to Predefined Credential Type.
- Set Credential Type to Idekavan SMS API.
- 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:
- Add the trigger and choose the Event:
- Any: each item gets
eventTypedeliveryReportorinboundMessage; - Delivery Report;
- Inbound Message.
- Any: each item gets
- Choose the HTTP Method Idekavan will use: POST for their JSON pushes, GET if you asked for query-string pushes.
- Optionally set Authentication to Basic Auth, and enter a Webhook Username and Webhook Password on an Idekavan SMS API credential.
- 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
statusCodeandstatusName. - Unrecognised shapes are passed on with
eventType: "unknown", never dropped. - Response. It answers
{"status":"accepted","events":N}immediately, and401when 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: 100andsucceededis notfalse.
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 geterrorCodeanderrorMessage. Filter onacceptedto 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.
- Accepted forms:
- Data coding. Idekavan's API document says Persian is
8and English is1. The production clients (theidk-messagingSDK and dobare) send the reverse:1for UCS-2/Persian and8for 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 }) }}, JavaScriptDates, and ISO text with an offset orZ) 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
401once, 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.