Programowanie 2026-04-30 9 min czytania

SMS API integracja REST — przewodnik dla programistów 2026

Krok-po-kroku integracja SMS API w 30 minut — REST endpoints, Bearer auth, webhook callbacks, biblioteki PHP/Node.js/Python, error handling, retry logic, two-way SMS, sandbox testing. Code examples gotowe do produkcji.

Pierwszy request — quickstart

# 1. Test endpoint (curl)
curl -X POST https://api.gmweb.pl/v1/sms \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "to": "+48500600700",
    "message": "Witaj! Test SMS API.",
    "from": "GMWEB",
    "webhookUrl": "https://yourapp.com/webhook"
  }'

# Response 200 OK
{
  "messageId": "msg_01HZ8X9YR2N3K4L5M6P7Q8R9S0",
  "status": "queued",
  "estimatedDelivery": "2026-04-30T10:00:05Z",
  "cost": { "currency": "PLN", "value": 0 }
}

# Webhook callback (po dostarczeniu)
POST https://yourapp.com/webhook
{
  "messageId": "msg_01HZ8X9YR2N3K4L5M6P7Q8R9S0",
  "status": "delivered",
  "deliveredAt": "2026-04-30T10:00:03.245Z",
  "operator": "Plus"
}

Node.js — produkcyjny przykład

import { GMWebSMS } from '@gmweb/sms'
import { randomUUID } from 'crypto'

const sms = new GMWebSMS({ apiKey: process.env.GMWEB_API_KEY! })

async function sendAppointmentReminder(phone: string, when: Date) {
  try {
    const result = await sms.send({
      to: phone,
      message: `Przypominamy: wizyta jutro ${when.toLocaleTimeString()}.
Odpowiedz TAK aby potwierdzić, NIE aby anulować.`,
      idempotencyKey: randomUUID(),
      webhookUrl: `${process.env.APP_URL}/webhooks/sms`,
    })
    return result.messageId
  } catch (err) {
    if (err.code === 'RATE_LIMITED') {
      // Retry z exponential backoff
      await new Promise(r => setTimeout(r, 2000))
      return sendAppointmentReminder(phone, when)
    }
    throw err
  }
}

// Webhook handler (Express)
app.post('/webhooks/sms', (req, res) => {
  const sig = req.headers['x-gmweb-signature']
  if (!sms.verifyWebhook(req.rawBody, sig)) {
    return res.status(401).send('Invalid signature')
  }
  const { messageId, status, deliveredAt } = req.body
  // Update DB...
  res.status(200).send('OK')
})

Endpoints API — podstawy

EndpointMethodOpis
/v1/smsPOSTWyślij pojedynczy SMS
/v1/sms/batchPOSTWyślij 100-1000 SMS w jednym request (bulk)
/v1/sms/{id}GETStatus pojedynczej wiadomości
/v1/sms/{id}DELETEAnuluj zaplanowaną wiadomość (jeśli jeszcze nie wysłana)
/v1/smsGETLista wiadomości (filter by status, date, threadId)
/v1/webhook/testPOSTTest webhook URL — wymusi callback
/v1/account/balanceGETStan konta i pozostałe SMS w abonamencie
/v1/account/quotaGETRate limits per second/minute/day

Webhook security — HMAC signature

// PHP — weryfikacja webhooka
$secret = $_ENV['GMWEB_WEBHOOK_SECRET'];
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_GMWEB_SIGNATURE'] ?? '';

$expected = hash_hmac('sha256', $payload, $secret);
if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

$data = json_decode($payload, true);
// Process: $data['messageId'], $data['status']

Error codes — co robić

400 BAD_REQUEST

Walidacja payloadu (numer E.164, długość treści ≤160 lub multipart). Fix: client-side validate przed wysłaniem.

401 UNAUTHORIZED

API key niepoprawny lub expired. Regeneruj w panelu.

402 PAYMENT_REQUIRED

Brak środków na koncie. Doładuj lub upgrade plan.

429 RATE_LIMITED

Exponential backoff retry: 1s, 2s, 4s, 8s, 16s. Sprawdź X-RateLimit-Remaining.

500 INTERNAL_ERROR

Po stronie bramki. Retry po 5-30s. Logi do support.

503 SERVICE_UNAVAILABLE

Maintenance lub overload. Retry exponential.

webhook_timeout

Twój endpoint nie zwrócił 200 OK w 3s. Bramka retry 3× z backoff.

invalid_phone

Numer w złym formacie. Użyj E.164: +48500600700.

FAQ

Jak zacząć z SMS API — pierwszy request?

Krok 1: rejestracja konta + KYC firmy (15 min). Krok 2: wygeneruj API key w panelu (Bearer token). Krok 3: wyślij testowy SMS curlem: curl -X POST https://api.gmweb.pl/sms -H "Authorization: Bearer YOUR_KEY" -H "Content-Type: application/json" -d '{"to":"+48500600700","message":"Test"}'. Odpowiedź 200 OK z messageId. Krok 4: skonfiguruj webhook URL dla statusu dostarczenia (delivered/failed). Krok 5: zainstaluj SDK (npm install @gmweb/sms-sdk dla Node.js, composer require gmweb/sms-sdk dla PHP). Total time: 30 minut do pierwszej wysłanej wiadomości produkcyjnej.

Jak obsłużyć rate limiting i retry?

Standard SMS API: 50-100 req/sec rate limit (zwracane w nagłówku X-RateLimit-Remaining). Best practices: (1) Exponential backoff przy 429 Too Many Requests: retry po 1s, 2s, 4s, 8s, 16s. (2) Idempotency keys (UUID v4) — dodaj nagłówek Idempotency-Key dla bezpiecznych retry bez duplikacji SMS. (3) Queue+worker pattern — RabbitMQ/Redis kolejka, worker pobiera z respektem rate limit. (4) Monitor X-RateLimit-Remaining → zwolnij workerów gdy <20%. (5) Bulk endpoint POST /sms/batch dla 100-1000 SMS w jednym call (efektywniej niż loop). Logi: zapisz każdy request+response (90 dni retention) dla debugowania.

Webhook security — jak zabezpieczyć endpoint?

Atak vector: ktoś podszywa się pod bramkę i wysyła fake webhook do Twojego endpointu. Zabezpieczenia: (1) HMAC SIGNATURE — bramka GMWEB podpisuje payload kluczem (HMAC-SHA256), Ty weryfikujesz: const sig = req.headers["x-gmweb-signature"]; const expected = crypto.createHmac("sha256", SECRET).update(req.body).digest("hex"); if (sig !== expected) return 401. (2) IP WHITELIST — webhook tylko z IP bramki (sprawdź dokumentację, GMWEB publishes static IPs). (3) HTTPS only — TLS 1.2+, nigdy plain HTTP. (4) Idempotency — sprawdzaj messageId przed processowaniem (uniknij double-processing przy retry). (5) Timeout response 200 OK w 3s — bramka zinterpretuje timeout jako fail i zretry. (6) Log każdy webhook — debug + audit.

Biblioteki klienckie — co jest dostępne?

GMWEB SDK: PHP (composer require gmweb/sms-sdk, autoload PSR-4), Node.js (npm install @gmweb/sms, TypeScript types included), Python (pip install gmweb-sms), Java (Maven artifact), .NET (NuGet package), Go (go get github.com/gmweb/sms-go). SMSAPI/SerwerSMS mają podobne SDK. Twilio ma 15 SDK (najbogatszy ekosystem) ale 3-5× droższy. Dla custom — REST API zawsze dostępne, plus generator OpenAPI 3.0 → autogen client w dowolnym języku. Webhook helpers: w SDK są built-in funkcje verifyWebhookSignature() — nie musisz pisać HMAC ręcznie.

Jak testować integrację bez wysyłania prawdziwych SMS?

Sandbox mode: bramki SMS oferują test environment gdzie SMS-y nie są dostarczane prawdziwe (oszczędność kosztów + bezpieczeństwo). GMWEB: api.gmweb.pl/v1/sandbox endpoint, testowe API key DEV_xxx, fake responses (success/fail symulowane). Webhooks dla sandbox: GMWEB pinguje Twój endpoint po 1-5 sekundach z statusem (możesz wymusić "failed" parametrem). Lokalna integracja: ngrok / cloudflared tunnel dla webhook callback z prawdziwego API: ngrok http 3000 → http://abc.ngrok.io/webhook → register w panelu. Unit tests: mock library (Jest, PHPUnit, pytest) z stubbed API responses.

Jak zaimplementować two-way SMS (chatbot)?

Workflow: (1) Klient odpisuje SMSem na Twój numer firmowy. (2) Bramka rejestruje incoming, pinguje webhook: POST /webhook { from, to, message, threadId, receivedAt }. (3) Twoja aplikacja parsuje (np. trigger keywords TAK/NIE/STOP/PROMO). (4) Wysyłka response: POST /sms z replyTo wskazaniem na incoming messageId (threading). (5) Bot logic — switch case na keywords lub LLM (OpenAI API z prompt "answer in 120 chars max"). Schema: ConversationalBot. Best practice: zawsze opcja "AGENT" do escalation human, max 3 round trips bot, potem switch human. Logging: każda konwersacja w DB z threadId dla audit/training.

Powiązane artykuły

Zacznij integrację SMS API w 30 minut

SDK Node.js/PHP/Python, sandbox mode, webhook HMAC, dokumentacja OpenAPI 3.0.

Zobacz API