Για developers

SMS API της PILAS

Στείλε SMS από το site, το e-shop ή την εφαρμογή σου με ένα απλό REST αίτημα. Κωδικοί επιβεβαίωσης, υπενθυμίσεις ραντεβού, ειδοποιήσεις παραγγελιών — με τους δικούς σου αποστολείς και χρέωση από το υπόλοιπο SMS του λογαριασμού σου.

REST + JSON Αναφορές παράδοσης Webhooks με υπογραφή Δωρεάν sandbox
curl -X POST https://www.pilas.gr/api/sms/v1/send \
  -H "Authorization: Bearer pk_live_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"to": "6912345678", "text": "Ο κωδικός σας είναι 4821"}'

Εισαγωγή

Το API δέχεται και επιστρέφει JSON πάνω από HTTPS. Όλα τα endpoints βρίσκονται κάτω από τη διεύθυνση:

Base URL
https://www.pilas.gr/api/sms/v1
Δικά σου SMSΚάθε μήνυμα χρεώνεται από το υπόλοιπο του λογαριασμού σου PILAS, όπως και οι αποστολές από το portal.
Δικοί σου αποστολείςΣτέλνεις μόνο με αποστολείς που έχουν εγκριθεί στον λογαριασμό σου.
Προστασία παραληπτώνΌποιος έχει ζητήσει διακοπή (STOP) εξαιρείται αυτόματα και δεν χρεώνεσαι.

Πώς ξεκινάς

  • Κάνε λογαριασμό και ζήτα πρόσβαση από τη σελίδα «API».
  • Μετά την έγκριση, φτιάξε ένα κλειδί Sandbox για δοκιμές και ένα Live για τις πραγματικές αποστολές.
  • Αγόρασε πακέτο SMS — τα SMS δεν λήγουν ποτέ.

Ταυτοποίηση

Κάθε κλήση στέλνει το κλειδί σου στην κεφαλίδα Authorization:

HTTP
Authorization: Bearer pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Εναλλακτικά δέχεται και την κεφαλίδα X-API-Key. Τα κλειδιά pk_live_… στέλνουν πραγματικά μηνύματα, τα pk_test_… δουλεύουν σε sandbox.

Κράτα το κλειδί στον server σου. Μην το βάζεις ποτέ σε κώδικα browser ή σε εφαρμογή κινητού — όποιος το έχει, στέλνει SMS από τον λογαριασμό σου. Αν διαρρεύσει, ανακάλεσέ το αμέσως από το «API» του λογαριασμού σου.

Αποστολή

POST /send — στέλνει ένα μήνυμα σε έναν ή περισσότερους παραλήπτες.

ΠεδίοΤύποςΠεριγραφή
tostring | arrayΚινητό ή λίστα κινητών. Δεκτά: 69XXXXXXXX, 3069XXXXXXXX, +3069…, διεθνή. Διπλότυπα αφαιρούνται.
textstringΤο μήνυμα, έως 1.000 χαρακτήρες. Στέλνεται σε κεφαλαία χωρίς τόνους (GSM-7).
messagesarrayΑντί για to/text: [{to, text, reference}] — διαφορετικό κείμενο ανά παραλήπτη.
senderstringΕγκεκριμένος αποστολέας σου. Αν λείπει, χρησιμοποιείται ο προεπιλεγμένος.
schedule_atstring | intΠρογραμματισμός: ISO 8601 ή unix timestamp, από 1 λεπτό έως 180 ημέρες μπροστά.
referencestringΔικό σου αναγνωριστικό (π.χ. αριθμός παραγγελίας), έως 80 χαρακτήρες.
curl -X POST https://www.pilas.gr/api/sms/v1/send \
  -H "Authorization: Bearer pk_live_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"to": "6912345678", "text": "Ο κωδικός σας είναι 4821"}'

Απάντηση

Για έως 10 παραλήπτες η απάντηση έρχεται με την τελική κατάσταση αποστολής. Για περισσότερους, τα μηνύματα επιστρέφονται ως queued και στέλνονται αμέσως μετά — η κατάσταση τους φαίνεται με GET /messages ή μέσω webhook.

JSON
{
  "ok": true,
  "batch_id": "bat_t3k9qx2f8a1c04e7b9",
  "mode": "live",
  "count": 1,
  "segments": 1,
  "credits_charged": 1,
  "summary": { "sent": 1 },
  "messages": [
    {
      "id": "msg_t3k9qx5d2e7a90c1f3",
      "batch_id": "bat_t3k9qx2f8a1c04e7b9",
      "to": "306912345678",
      "sender": "MYBRAND",
      "text": "Ο ΚΩΔΙΚΟΣ ΣΑΣ ΕΙΝΑΙ 4821",
      "segments": 1,
      "status": "sent",
      "error": null,
      "reference": null,
      "mode": "live",
      "credits_charged": 1,
      "created_at": "2026-11-02T10:15:04+02:00",
      "sent_at": "2026-11-02T10:15:05+02:00",
      "delivered_at": null
    }
  ],
  "balance": 4210
}
Χρέωση: 1 SMS = 160 χαρακτήρες (153 για κάθε επόμενο τμήμα σε μεγαλύτερα μηνύματα). Τα SMS δεσμεύονται πριν την αποστολή και επιστρέφονται αυτόματα όταν ένα μήνυμα δεν μπορεί να σταλεί ή ακυρώνεται.

Πολλοί παραλήπτες

Το to δέχεται πίνακα έως 1.000 αριθμών με το ίδιο κείμενο. Για διαφορετικό κείμενο ανά παραλήπτη χρησιμοποίησε το messages:

JSON
{
  "sender": "MYBRAND",
  "messages": [
    { "to": "6912345678", "text": "Η παραγγελία 1042 στάλθηκε", "reference": "order-1042" },
    { "to": "6987654321", "text": "Η παραγγελία 1043 στάλθηκε", "reference": "order-1043" }
  ]
}

Αν έστω ένας αριθμός ή ένα κείμενο δεν είναι έγκυρο, η κλήση απορρίπτεται ολόκληρη με 422 και τη λίστα invalid — δεν στέλνεται τίποτα και δεν χρεώνεσαι.

Προγραμματισμός

Πρόσθεσε schedule_at για αποστολή αργότερα (από 1 λεπτό έως 180 ημέρες). Χωρίς ζώνη ώρας, η ώρα θεωρείται ώρα Ελλάδας.

JSON
{
  "to": ["6912345678", "6987654321"],
  "text": "Υπενθύμιση: το ραντεβού σας είναι αύριο στις 10:00",
  "schedule_at": "2026-11-05T18:00:00+02:00"
}

Η απάντηση έρχεται με 202 και τα μηνύματα σε κατάσταση scheduled. Τα SMS δεσμεύονται τη στιγμή του προγραμματισμού. Ακύρωση:

cURL
curl -X POST https://www.pilas.gr/api/sms/v1/messages/msg_t3k9qx5d2e7a90c1f3/cancel \
  -H "Authorization: Bearer pk_live_xxxxxxxx"

# ή όλη την αποστολή
curl -X POST https://www.pilas.gr/api/sms/v1/batches/bat_t3k9qx2f8a1c04e7b9/cancel \
  -H "Authorization: Bearer pk_live_xxxxxxxx"

Κατάσταση & ιστορικό

GET /messages/{id} επιστρέφει ένα μήνυμα. GET /messages επιστρέφει το ιστορικό, με φίλτρα status, batch_id, reference, to, mode, from, until και σελιδοποίηση page / per_page (έως 100).

cURL
curl "https://www.pilas.gr/api/sms/v1/messages?status=failed&from=2026-11-01&per_page=50" \
  -H "Authorization: Bearer pk_live_xxxxxxxx"

Τιμές κατάστασης

statusΣημασία
queuedΣε ουρά για αποστολή
scheduledΠρογραμματισμένο — μπορεί να ακυρωθεί
sendingΑποστέλλεται τώρα
sentΠαραδόθηκε στο δίκτυο κινητής
deliveredΕπιβεβαιώθηκε η παράδοση στη συσκευή
failedΑπέτυχε (δες error) — αν δεν στάλθηκε, τα SMS επιστρέφονται
rejectedΔεν στάλθηκε: ο παραλήπτης έχει ζητήσει διακοπή (STOP) — χωρίς χρέωση
canceledΑκυρώθηκε — τα SMS επιστράφηκαν

Όλα τα endpoints

ΜέθοδοςEndpointΤι κάνει
POST/sendΑποστολή σε έναν ή πολλούς παραλήπτες (άμεσα ή προγραμματισμένα)
GET/messages/{id}Κατάσταση ενός μηνύματος
GET/messagesΙστορικό με φίλτρα και σελιδοποίηση
GET/batches/{batch_id}Σύνοψη και μηνύματα μιας αποστολής
POST/messages/{id}/cancelΑκύρωση προγραμματισμένου μηνύματος (επιστροφή SMS)
POST/batches/{batch_id}/cancelΑκύρωση όλων των προγραμματισμένων μιας αποστολής
GET/balanceΥπόλοιπο SMS, όρια και κατανάλωση ημέρας
GET/sendersΟι εγκεκριμένοι αποστολείς σου
POST/webhook/testΔοκιμαστικό webhook προς το URL σου

Υπόλοιπο & αποστολείς

GET /balance επιστρέφει τα διαθέσιμα SMS, τα όρια και τα μηνύματα της ημέρας. GET /senders επιστρέφει τους εγκεκριμένους αποστολείς σου και ποιος είναι ο προεπιλεγμένος.

JSON
{
  "ok": true,
  "mode": "live",
  "credits": 4210,
  "unit": "SMS",
  "limits": { "per_minute": 60, "per_day": 2000, "used_today": 148, "max_recipients_per_request": 1000 }
}

Webhooks

Όρισε ένα https:// URL στη σελίδα «API» του λογαριασμού σου. Κάθε φορά που αλλάζει η κατάσταση ενός μηνύματος σου στέλνουμε POST με event message.sent, message.delivered, message.failed, message.rejected ή message.canceled:

JSON
{
  "event": "message.delivered",
  "created": 1762071310,
  "data": {
    "id": "msg_t3k9qx5d2e7a90c1f3",
    "batch_id": "bat_t3k9qx2f8a1c04e7b9",
    "to": "306912345678",
    "status": "delivered",
    "reference": "order-1042",
    "delivered_at": "2026-11-02T10:15:09+02:00"
  }
}

Απάντησε με οποιοδήποτε 2xx μέσα σε 6 δευτερόλεπτα. Αν αποτύχει, ξαναδοκιμάζουμε έως 6 φορές (μετά από 1′, 5′, 30′, 2 ώρες και 6 ώρες).

Έλεγχος υπογραφής

Κάθε webhook έχει κεφαλίδα X-Pilas-Signature: t=<unix>,v1=<hex>, όπου v1 = HMAC-SHA256(μυστικό, "t.σώμα"). Έλεγξέ την πριν εμπιστευτείς το αίτημα:

<?php
$secret = getenv('PILAS_WEBHOOK_SECRET'); // whsec_…
$body   = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_PILAS_SIGNATURE'] ?? '';

preg_match('/t=(\d+),v1=([a-f0-9]+)/', $header, $m);
$expected = hash_hmac('sha256', $m[1] . '.' . $body, $secret);

if (!$m || !hash_equals($expected, $m[2]) || abs(time() - (int)$m[1]) > 300) {
  http_response_code(400); exit;
}
$event = json_decode($body, true);
// … ενημέρωσε τη βάση σου με $event['data']['status']
http_response_code(200);

Sandbox

Με κλειδί pk_test_… το API συμπεριφέρεται ακριβώς όπως στην παραγωγή — επικύρωση, απαντήσεις, webhooks — αλλά κανένα SMS δεν φεύγει και τίποτα δεν χρεώνεται. Τα μηνύματα γίνονται αμέσως delivered.

Για να δοκιμάσεις αποτυχία, στείλε σε αριθμό που τελειώνει σε 0000: το μήνυμα γίνεται failed με error simulated_failure.

Όρια & idempotency

  • 60 κλήσεις ανά λεπτό και 2.000 μηνύματα την ημέρα ανά λογαριασμό (αυξάνονται κατόπιν αιτήματος).
  • Έως 1.000 παραλήπτες ανά κλήση, κείμενο έως 1.000 χαρακτήρες.
  • Όταν ξεπεραστεί όριο, η απάντηση είναι 429 με κεφαλίδα Retry-After.

Για να μη σταλεί ποτέ κάτι δύο φορές (π.χ. σε επανάληψη μετά από timeout), στείλε την κεφαλίδα Idempotency-Key με μοναδική τιμή ανά αποστολή. Για 24 ώρες, η ίδια τιμή επιστρέφει την αρχική απάντηση χωρίς νέα αποστολή ή χρέωση.

cURL
curl -X POST https://www.pilas.gr/api/sms/v1/send \
  -H "Authorization: Bearer pk_live_xxxxxxxx" \
  -H "Idempotency-Key: order-1042-shipped" \
  -H "Content-Type: application/json" \
  -d '{"to": "6912345678", "text": "Η παραγγελία σας στάλθηκε"}'

Σφάλματα

Κάθε σφάλμα επιστρέφει "ok": false με σταθερό code για τον κώδικά σου και ελληνικό message για τους χρήστες σου:

JSON
{
  "ok": false,
  "error": {
    "code": "insufficient_credits",
    "message": "Δεν υπάρχουν αρκετά SMS. Χρειάζονται 120, υπόλοιπο 80.",
    "credits_needed": 120,
    "balance": 80
  }
}
HTTPcodeΠότε
400invalid_jsonΤο σώμα δεν είναι έγκυρο JSON
401missing_api_key / invalid_api_keyΛείπει ή δεν ισχύει το κλειδί
402insufficient_creditsΔεν φτάνει το υπόλοιπο SMS — δεν στάλθηκε τίποτα
403api_access_inactive / account_inactiveΗ πρόσβαση είναι σε αναστολή ή ο λογαριασμός ανενεργός
404not_foundΆγνωστο id ή endpoint
405method_not_allowedΛάθος μέθοδος HTTP
409not_cancelable / idempotency_in_progressΔεν ακυρώνεται πια / η ίδια κλήση εκτελείται ήδη
422invalid_recipients, sender_not_approved, invalid_schedule, content_not_allowed …Λάθος στα δεδομένα — δεν στάλθηκε τίποτα
429rate_limited / daily_limit_exceededΞεπεράστηκε όριο — δες Retry-After
503service_unavailableΠροσωρινή αδυναμία — ξαναδοκίμασε αργότερα

Έτοιμος να ξεκινήσεις;

Ζήτα πρόσβαση και δοκίμασε δωρεάν με κλειδί sandbox.

Ζήτα πρόσβαση