Developer documentation

GroSMS API Reference

Send SMS, run bulk campaigns, verify OTPs, and manage contacts and credits — all through one REST API. Every request is authenticated with an API key from your dashboard, sent in the x-api-key header.

First request in 60 seconds

curl -X POST 'https://api.grosms.com/api/messages/send' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"to":"9800000000","message":"Hello from GroSMS!"}'

Base URL: https://api.grosms.com/api. Generate a key from your dashboard under Settings → API Keys, then paste it into the box below to turn every example on this page into a live request.

Authorize with your API key to enable Try it now.

SMS & Templates

Send single messages, dispatch bulk campaigns, check delivery status, and manage reusable message templates.

POST /messages/send

Send a single SMS to one recipient.

POSTAPI key required
ParamTypeRequiredDescription
tostringYesRecipient phone number (10-digit local or 13-digit with 977 country code, must start 97/98).
messagestringYesMessage body.

Example response

{
  "message_id": 501,
  "status": "queued"
}
StatusErrorWhen
400to is required`to` missing from body
400message is required`message` missing from body
400Phone number must be 10 or 13 digitsinvalid phone format
401API key requiredx-api-key header missing
401Invalid or inactive API keykey does not match an active key
curl -X POST 'https://api.grosms.com/api/messages/send' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"to":"9800000000","message":"Hello from GroSMS!"}'

GET /messages/send/:id

Get the delivery status of a message you sent via the API.

GETAPI key required
ParamTypeRequiredDescription
idnumberYesMessage ID returned by Send SMS.

Example response

{
  "message": {
    "id": 501,
    "recipient": "9800000000",
    "body": "Hello from GroSMS!",
    "status": "delivered",
    "segments": 1,
    "charset": "gsm",
    "sent_at": "2026-07-11T09:00:00.000Z",
    "delivered_at": "2026-07-11T09:00:03.000Z"
  }
}
StatusErrorWhen
404Message not foundid does not belong to this API key's account
401API key requiredx-api-key header missing
401Invalid or inactive API keykey does not match an active key
curl -X GET 'https://api.grosms.com/api/messages/send/501' \
  -H 'x-api-key: YOUR_API_KEY'

GET /messages

List sent messages with pagination and status filtering.

GETAPI key required
ParamTypeRequiredDescription
pagenumberNoPage number, default 1.
limitnumberNoPage size, default 50, max 100.
statusstringNoFilter: queued | sent | delivered | failed | rejected.

Example response

{
  "messages": [
    {
      "id": 501,
      "recipient": "9800000000",
      "body": "Hello!",
      "status": "delivered"
    }
  ],
  "pagination": {
    "total": 1,
    "page": 1,
    "limit": 50,
    "pages": 1
  }
}
StatusErrorWhen
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/messages?page=1&limit=50&status=delivered' \
  -H 'x-api-key: YOUR_API_KEY'

GET /messages/:id

Get a single message by ID, including campaign and contact info.

GETAPI key required
ParamTypeRequiredDescription
idnumberYesMessage ID.

Example response

{
  "message": {
    "id": 501,
    "recipient": "9800000000",
    "body": "Hello!",
    "status": "delivered",
    "campaign": null,
    "contact": null
  }
}
StatusErrorWhen
404Message not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/messages/501' \
  -H 'x-api-key: YOUR_API_KEY'

GET /campaigns

List all bulk SMS campaigns.

GETAPI key required

Example response

{
  "campaigns": [
    {
      "id": 1,
      "name": "Promo Blast",
      "status": "draft",
      "recipient_count": 120
    }
  ]
}
StatusErrorWhen
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/campaigns' \
  -H 'x-api-key: YOUR_API_KEY'

GET /campaigns/:id

Get a campaign with its recipient list.

GETAPI key required
ParamTypeRequiredDescription
idnumberYesCampaign ID.

Example response

{
  "campaign": {
    "id": 1,
    "name": "Promo Blast",
    "message": "Hello!",
    "status": "draft",
    "campaignRecipients": []
  }
}
StatusErrorWhen
404Campaign not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/campaigns/1' \
  -H 'x-api-key: YOUR_API_KEY'

POST /campaigns

Create a draft campaign.

POSTAPI key required
ParamTypeRequiredDescription
namestringYesCampaign name.
messagestringYesMessage body sent to every recipient.
scheduled_atstringNoISO datetime to schedule for (not auto-sent yet).

Example response

{
  "campaign": {
    "id": 1,
    "name": "Promo Blast",
    "status": "draft",
    "recipient_count": 0
  }
}
StatusErrorWhen
400Name and message are requiredmissing name or message
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X POST 'https://api.grosms.com/api/campaigns' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Promo Blast","message":"Big sale this weekend!","scheduled_at":"2026-08-01T09:00:00.000Z"}'

PUT /campaigns/:id

Update a campaign's name, message, status, or schedule.

PUTAPI key required
ParamTypeRequiredDescription
idnumberYesCampaign ID.
namestringYesCampaign name.
messagestringYesMessage body.
statusstringNodraft | scheduled | sent | cancelled.

Example response

{
  "campaign": {
    "id": 1,
    "name": "Promo Blast v2",
    "status": "scheduled"
  }
}
StatusErrorWhen
404Campaign not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X PUT 'https://api.grosms.com/api/campaigns/1' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Promo Blast v2","message":"Updated offer!","status":"scheduled"}'

DELETE /campaigns/:id

Delete a campaign and its recipient links.

DELETEAPI key required
ParamTypeRequiredDescription
idnumberYesCampaign ID.

Example response

{
  "message": "Campaign deleted successfully"
}
StatusErrorWhen
404Campaign not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X DELETE 'https://api.grosms.com/api/campaigns/1' \
  -H 'x-api-key: YOUR_API_KEY'

POST /campaigns/:id/recipients

Add a phone number to a campaign's audience (creates the contact if it doesn't exist).

POSTAPI key required
ParamTypeRequiredDescription
idnumberYesCampaign ID.
phonestringYesRecipient phone number.

Example response

{
  "recipient": {
    "id": 55,
    "campaign_id": 1,
    "contact_id": 10
  },
  "contact": {
    "id": 10,
    "phone": "9800000000"
  },
  "isNew": true
}
StatusErrorWhen
404Campaign not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X POST 'https://api.grosms.com/api/campaigns/1/recipients' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"phone":"9800000000"}'

POST /campaigns/:id/send

`{{name}}`/`{{phone}}` in the campaign's message are replaced with each recipient's own contact info. Debits credits for the sum of every recipient's message-segment count, then queues one personalized message per recipient. `total_cost` reflects the credit amount for metered accounts — accounts with no per-message rate configured are not actually charged even though this field is still populated.

POSTAPI key required
ParamTypeRequiredDescription
idnumberYesCampaign ID (must be in draft status with at least one recipient).

Example response

{
  "campaign": {
    "id": 1,
    "name": "Promo Blast",
    "status": "sent"
  },
  "sent_count": 120,
  "total_cost": 137
}
StatusErrorWhen
404Campaign not foundid does not belong to this API key's account
400Campaign has already been sent or is not in draft statusstatus is not draft
400Campaign has no recipientsno recipients added yet
400Insufficient credits. Please load credits to continue.balance can't cover the sum of every recipient's message-segment count
401API key requiredx-api-key header missing
401Invalid or inactive API keykey does not match an active key
curl -X POST 'https://api.grosms.com/api/campaigns/1/send' \
  -H 'x-api-key: YOUR_API_KEY'

GET /templates

List saved SMS templates.

GETAPI key required

Example response

{
  "templates": [
    {
      "id": 1,
      "name": "Welcome",
      "body": "Hi {{name}}, welcome to GroSMS!"
    }
  ]
}
StatusErrorWhen
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/templates' \
  -H 'x-api-key: YOUR_API_KEY'

GET /templates/:id

Get a single template.

GETAPI key required
ParamTypeRequiredDescription
idnumberYesTemplate ID.

Example response

{
  "template": {
    "id": 1,
    "name": "Welcome",
    "body": "Hi {{name}}, welcome to GroSMS!"
  }
}
StatusErrorWhen
404Template not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/templates/1' \
  -H 'x-api-key: YOUR_API_KEY'

POST /templates

Create a template. `{{name}}` placeholder syntax is stored as-is, not server-interpolated.

POSTAPI key required
ParamTypeRequiredDescription
namestringYesTemplate name.
bodystringYesTemplate body.

Example response

{
  "template": {
    "id": 1,
    "name": "Welcome",
    "body": "Hi {{name}}, welcome to GroSMS!"
  }
}
StatusErrorWhen
400Name and body are requiredmissing name or body
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X POST 'https://api.grosms.com/api/templates' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Welcome","body":"Hi {{name}}, welcome to GroSMS!"}'

PUT /templates/:id

Update a template.

PUTAPI key required
ParamTypeRequiredDescription
idnumberYesTemplate ID.
namestringYesTemplate name.
bodystringYesTemplate body.

Example response

{
  "template": {
    "id": 1,
    "name": "Welcome v2",
    "body": "Hi {{name}}, thanks for joining!"
  }
}
StatusErrorWhen
404Template not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X PUT 'https://api.grosms.com/api/templates/1' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Welcome v2","body":"Hi {{name}}, thanks for joining!"}'

DELETE /templates/:id

Delete a template.

DELETEAPI key required
ParamTypeRequiredDescription
idnumberYesTemplate ID.

Example response

{
  "message": "Template deleted successfully"
}
StatusErrorWhen
404Template not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X DELETE 'https://api.grosms.com/api/templates/1' \
  -H 'x-api-key: YOUR_API_KEY'

OTP

Generate and verify one-time passcodes for login, signup, or transaction confirmation. Requires an OTP template configured in your dashboard first.

POST /otp/generate

Generate and send an OTP using a template created in your GroSMS dashboard.

POSTAPI key required
ParamTypeRequiredDescription
templateIdnumberYesOTP template ID from your dashboard (Settings → OTP Templates).
phonestringYesRecipient phone number.
parametersobjectNoValues for any caller variables the template uses: first_name, last_name, email, user_id.

Example response

{
  "token": "9f1c2e...64hex",
  "phone": "9800000000"
}
StatusErrorWhen
400templateId and phone are requiredmissing required field
404Template not foundtemplateId doesn't belong to this account
400Missing required parameter(s): first_nametemplate needs a caller variable you didn't supply
502Failed to send OTP SMSSMS gateway send failed
401API key requiredx-api-key header missing
401Invalid or inactive API keykey does not match an active key
curl -X POST 'https://api.grosms.com/api/otp/generate' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"templateId":5,"phone":"9800000000","parameters":"{\"first_name\":\"Sita\"}"}'

POST /otp/verify

Verify an OTP code against the token returned by Generate OTP.

POSTAPI key required
ParamTypeRequiredDescription
tokenstringYesToken from Generate OTP.
codestringYes6-digit code the user received.

Example response

{
  "message": "OTP verified successfully",
  "phone": "9800000000"
}
StatusErrorWhen
400Invalid OTP tokentoken unknown or belongs to another account
400OTP has expiredmore than 5 minutes since generation
400OTP already verifiedtoken already used
400Invalid OTP codecode does not match
429Maximum OTP attempts exceeded5 wrong attempts made
401API key requiredx-api-key header missing
401Invalid or inactive API keykey does not match an active key
curl -X POST 'https://api.grosms.com/api/otp/verify' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"token":"9f1c2e...64hex","code":"384729"}'

GET /otp/status

Check the verification status of an OTP request.

GETAPI key required
ParamTypeRequiredDescription
tokenstringYesToken from Generate OTP.

Example response

{
  "verified_at": null,
  "attempts": 1,
  "max_attempts": 5,
  "expires_at": "2026-07-11T09:05:00.000Z",
  "expired": false
}
StatusErrorWhen
400Token is requiredquery param missing
404OTP request not foundtoken unknown or belongs to another account
401API key requiredx-api-key header missing
401Invalid or inactive API keykey does not match an active key
curl -X GET 'https://api.grosms.com/api/otp/status?token=9f1c2e...64hex' \
  -H 'x-api-key: YOUR_API_KEY'

Contacts

Manage your recipient list and organize contacts into groups for targeted campaigns.

GET /contacts

List contacts, optionally filtered by group.

GETAPI key required
ParamTypeRequiredDescription
group_idnumberNoFilter by contact group ID.

Example response

{
  "contacts": [
    {
      "id": 10,
      "name": "Sita Rai",
      "phone": "9800000000",
      "group": {
        "id": 3,
        "name": "VIP"
      }
    }
  ]
}
StatusErrorWhen
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/contacts?group_id=3' \
  -H 'x-api-key: YOUR_API_KEY'

GET /contacts/:id

Get a single contact.

GETAPI key required
ParamTypeRequiredDescription
idnumberYesContact ID.

Example response

{
  "contact": {
    "id": 10,
    "name": "Sita Rai",
    "phone": "9800000000",
    "group": null
  }
}
StatusErrorWhen
404Contact not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/contacts/10' \
  -H 'x-api-key: YOUR_API_KEY'

POST /contacts

Create a contact.

POSTAPI key required
ParamTypeRequiredDescription
namestringYesContact name.
phonestringYesPhone number.
group_idnumberNoContact group ID.

Example response

{
  "contact": {
    "id": 10,
    "name": "Sita Rai",
    "phone": "9800000000",
    "group": null
  }
}
StatusErrorWhen
400Name and phone are requiredmissing name or phone
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X POST 'https://api.grosms.com/api/contacts' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Sita Rai","phone":"9800000000","group_id":3}'

PUT /contacts/:id

Update a contact.

PUTAPI key required
ParamTypeRequiredDescription
idnumberYesContact ID.
namestringYesContact name.
phonestringYesPhone number.
group_idnumberNoContact group ID.

Example response

{
  "contact": {
    "id": 10,
    "name": "Sita Rai Thapa",
    "phone": "9800000000",
    "group": null
  }
}
StatusErrorWhen
404Contact not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X PUT 'https://api.grosms.com/api/contacts/10' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Sita Rai Thapa","phone":"9800000000","group_id":3}'

DELETE /contacts/:id

Delete a contact.

DELETEAPI key required
ParamTypeRequiredDescription
idnumberYesContact ID.

Example response

{
  "message": "Contact deleted successfully"
}
StatusErrorWhen
404Contact not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X DELETE 'https://api.grosms.com/api/contacts/10' \
  -H 'x-api-key: YOUR_API_KEY'

GET /contact-groups

List contact groups with member counts.

GETAPI key required

Example response

{
  "groups": [
    {
      "id": 3,
      "name": "VIP",
      "contact_count": 42
    }
  ]
}
StatusErrorWhen
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/contact-groups' \
  -H 'x-api-key: YOUR_API_KEY'

POST /contact-groups

Create a contact group.

POSTAPI key required
ParamTypeRequiredDescription
namestringYesGroup name.

Example response

{
  "group": {
    "id": 3,
    "name": "VIP",
    "contact_count": 0
  }
}
StatusErrorWhen
400Group name is requiredmissing name
409Group already existsname already used by this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X POST 'https://api.grosms.com/api/contact-groups' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"VIP"}'

PUT /contact-groups/:id

Rename a contact group.

PUTAPI key required
ParamTypeRequiredDescription
idnumberYesGroup ID.
namestringYesNew group name.

Example response

{
  "group": {
    "id": 3,
    "name": "Platinum"
  }
}
StatusErrorWhen
400Group name is requiredmissing name
404Group not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X PUT 'https://api.grosms.com/api/contact-groups/3' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Platinum"}'

DELETE /contact-groups/:id

Delete a contact group. Members are kept, ungrouped.

DELETEAPI key required
ParamTypeRequiredDescription
idnumberYesGroup ID.

Example response

{
  "message": "Group deleted"
}
StatusErrorWhen
404Group not foundid does not belong to this account
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X DELETE 'https://api.grosms.com/api/contact-groups/3' \
  -H 'x-api-key: YOUR_API_KEY'

Credits

Check your available SMS credit balance and review your transaction history.

GET /credits

Check your available SMS credit balance.

GETAPI key required

Example response

{
  "available": 5000,
  "usable": 4800,
  "hold": 200,
  "rate": 0.85
}
StatusErrorWhen
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/credits' \
  -H 'x-api-key: YOUR_API_KEY'

GET /credits/transactions

List your credit transaction history.

GETAPI key required
ParamTypeRequiredDescription
pagenumberNoPage number, default 1.
limitnumberNoPage size, default 50, max 100.

Example response

{
  "transactions": [
    {
      "id": 1,
      "type": "campaign",
      "amount": -120,
      "description": "Campaign \"Promo Blast\" send (120 recipients)"
    }
  ],
  "pagination": {
    "total": 1,
    "page": 1,
    "limit": 50,
    "pages": 1
  }
}
StatusErrorWhen
401Authentication requiredthis endpoint still requires dashboard login (Bearer token), not an API key — see badge above
curl -X GET 'https://api.grosms.com/api/credits/transactions?page=1&limit=50' \
  -H 'x-api-key: YOUR_API_KEY'