### Install Go SDK Source: https://docs.sent.dm/sdks/go Install the Sent Go SDK using go get. You can install the latest version or pin a specific version. ```go go get github.com/sentdm/sent-dm-go ``` ```go go get github.com/sentdm/sent-dm-go@v0.17.0 ``` -------------------------------- ### Installation Source: https://docs.sent.dm/llms-full.txt Install the Sent.dm Go SDK using go get. You can install the latest version or pin a specific version. ```bash go get github.com/sentdm/sent-dm-go # To pin a specific version: go get github.com/sentdm/sent-dm-go@v0.17.0 ``` -------------------------------- ### Install and Run ngrok for Local Webhook Testing Source: https://docs.sent.dm/start/webhooks/getting-started Install ngrok globally, start your local development server, and then create a tunnel to expose your local server to the internet. This is essential for testing Sent webhooks during development. ```bash # Install ngrok (if not already installed) npm install -g @ngrok/ngrok # Start your local server npm run dev # Running on http://localhost:5000 # In another terminal, create tunnel ngrok http 5000 ``` -------------------------------- ### Example Per-Article URL Source: https://docs.sent.dm/llms-full.txt An example of a plain-text URL for a specific article, the 'Sending Messages' guide. ```text https://docs.sent.dm/llms/start/guides/sending-messages.txt ``` -------------------------------- ### Go Project Setup and Dependencies Source: https://docs.sent.dm/llms-full.txt Initialize a Go module and install necessary dependencies for Gin integration, including the Sent DM Go SDK, Viper for configuration, and Swagger for API documentation. ```bash go mod init sent-gin-service go get github.com/gin-gonic/gin github.com/sentdm/sent-dm-go github.com/spf13/viper go get github.com/swaggo/swag github.com/swaggo/gin-swagger golang.org/x/time/rate ``` -------------------------------- ### Complete Profile Setup Source: https://docs.sent.dm/llms.txt Completes the setup process for a profile. ```APIDOC ## POST /profiles/{profileId}/complete-setup ### Description Completes the setup process for a profile. ### Method POST ### Endpoint /profiles/{profileId}/complete-setup ``` -------------------------------- ### Install Dependencies with bun Source: https://docs.sent.dm/sdks/typescript/integrations/nextjs Install the Sent DM SDK and Zod for validation using bun. ```bash bun add @sentdm/sentdm zod ``` -------------------------------- ### CI/CD Environment Setup for Tests Source: https://docs.sent.dm/sdks/testing Configure a GitHub Actions workflow for running tests on push or pull request events. This includes checking out code, setting up Node.js, installing dependencies, and running unit and integration tests. ```yaml # .github/workflows/test.yml name: Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18' - name: Install dependencies run: npm ci - name: Run unit tests run: npm test - name: Run integration tests env: SENT_DM_API_KEY_TEST: ${{ secrets.SENT_DM_API_KEY_TEST }} run: npm run test:integration ``` -------------------------------- ### Install Sent SDK with Go Source: https://docs.sent.dm/sdks Use this command to install the Sent SDK for Go projects. ```bash go get github.com/sentdm/sent-dm-go ``` -------------------------------- ### Install PHP SDK using Composer Source: https://docs.sent.dm/sdks/php Install the Sent PHP SDK using Composer. You can install the latest version or a specific version. ```bash composer require sentdm/sent-dm-php ``` ```bash composer require "sentdm/sent-dm-php 0.17.0" ``` -------------------------------- ### Install Dependencies with npm Source: https://docs.sent.dm/sdks/typescript/integrations/nextjs Install the Sent DM SDK and Zod for validation using npm. ```bash npm install @sentdm/sentdm zod npm install -D @types/node ``` -------------------------------- ### Install Dependencies with pnpm Source: https://docs.sent.dm/sdks/typescript/integrations/nextjs Install the Sent DM SDK and Zod for validation using pnpm. ```bash pnpm add @sentdm/sentdm zod pnpm add -D @types/node ``` -------------------------------- ### Send your first message Source: https://docs.sent.dm/sdks/csharp A quick start example showing how to send a message using the SentClient. It includes setting up message parameters like recipients, channel, and template with custom parameters. ```APIDOC ```csharp using Sentdm; using Sentdm.Models.Messages; using System.Collections.Generic; SentClient client = new(); MessageSendParams parameters = new() { To = new List { "+1234567890" }, Channel = new List { "sms", "whatsapp", "rcs" }, Template = new MessageSendParamsTemplate { Id = "7ba7b820-9dad-11d1-80b4-00c04fd430c8", Name = "welcome", Parameters = new Dictionary() { { "name", "John Doe" }, { "order_id", "12345" } } } }; var response = await client.Messages.Send(parameters); Console.WriteLine($"Sent: {response.Data.Recipients[0].MessageID}"); Console.WriteLine($"Status: {response.Data.Status}"); ``` ``` -------------------------------- ### Start Local Webhook Server Source: https://docs.sent.dm/start/webhooks/local-development Initializes and starts a local HTTP server to listen for incoming webhooks on port 3000. It validates the presence of the SENT_WEBHOOK_SECRET environment variable before starting. ```Go // Validate required environment variables if os.Getenv("SENT_WEBHOOK_SECRET") == "" { log.Fatal("SENT_WEBHOOK_SECRET environment variable is required") } http.HandleFunc("/webhooks/sent", webhookHandler) log.Println("Webhook server listening on port 3000") log.Fatal(http.ListenAndServe(":3000", nil)) ``` -------------------------------- ### Install Dependencies with yarn Source: https://docs.sent.dm/sdks/typescript/integrations/nextjs Install the Sent DM SDK and Zod for validation using yarn. ```bash yarn add @sentdm/sentdm zod yarn add -D @types/node ``` -------------------------------- ### Configure Client with Request Options Source: https://docs.sent.dm/sdks/go Shows how to initialize the client with global request options, such as adding headers, and how to override these options for individual requests. ```go client := sentdm.NewClient( // Adds a header to every request made by the client option.WithHeader("X-Some-Header", "custom_header_info"), ) // Override per-request response, err := client.Messages.Send(ctx, params, option.WithHeader("X-Some-Header", "some_other_value"), option.WithJSONSet("custom.field", map[string]string{"my": "object"}), ) ``` -------------------------------- ### Main Echo Application Setup Source: https://docs.sent.dm/sdks/go/integrations/echo This snippet shows the complete setup for a main Echo application, including configuration, logging, service initialization, middleware, route registration, and graceful shutdown. It's designed for the entry point of an Echo-based service. ```go // cmd/api/main.go package main import ( "context" "net/http" "os" "os/signal" "syscall" "time" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/sentdm/sent-dm-go/sent-echo-app/internal/config" "github.com/sentdm/sent-dm-go/sent-echo-app/internal/handler" appmiddleware "github.com/sentdm/sent-dm-go/sent-echo-app/internal/middleware" "github.com/sentdm/sent-dm-go/sent-echo-app/internal/service" appvalidator "github.com/sentdm/sent-dm-go/sent-echo-app/internal/validator" "github.com/sentdm/sent-dm-go/sent-echo-app/pkg/sentclient" "go.uber.org/zap" ) func main() { cfg, err := config.Load() if err != nil { panic(err) } logger, err := config.NewLogger(cfg.Log) if err != nil { panic(err) } defer logger.Sync() sentClient := sentclient.New(cfg.Sent.APIKey, logger) messageService := service.NewMessageService(sentClient, logger) webhookService := service.NewWebhookService(sentClient, logger, cfg.Sent.WebhookSecret) e := echo.New() e.HideBanner = true e.Validator = appvalidator.New() e.HTTPErrorHandler = appmiddleware.ErrorHandler(logger) e.Use(middleware.RequestID()) e.Use(appmiddleware.Logger(logger)) e.Use(middleware.Recover()) e.Use(middleware.CORS()) e.Use(middleware.Secure()) e.Use(middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(cfg.RateLimit.RequestsPerSecond))) handler.NewHealthHandler().Register(e) handler.NewMessageHandler(messageService, logger).Register(e) handler.NewWebhookHandler(webhookService, logger).Register(e) srv := &http.Server{ Addr: ": ``` -------------------------------- ### Header-Based Authentication Example Source: https://docs.sent.dm/reference/api/authentication This example demonstrates how to make a GET request to the /v3/contacts endpoint using header-based authentication with the x-api-key. ```APIDOC ## GET /v3/contacts ### Description This endpoint retrieves a list of contacts. Authentication is required. ### Method GET ### Endpoint https://api.sent.dm/v3/contacts ### Parameters #### Headers - **x-api-key** (string) - Required - Your secret API key for authentication. - **Content-Type** (string) - Required - Set to application/json. ### Request Example ```curl curl -X GET https://api.sent.dm/v3/contacts \ -H "x-api-key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \ -H "Content-Type: application/json" ``` ### Response #### Success Response (200) - **field1** (type) - Description #### Response Example { "example": "response body" } ### Common Authentication Errors #### Missing API Key (401) ```json { "success": false, "error": { "code": "AUTH_001", "message": "User is not authenticated", "doc_url": "https://docs.sent.dm/errors/AUTH_001" }, "meta": { "request_id": "req_xxx", "timestamp": "2024-01-01T00:00:00Z", "version": "v3" } } ``` **Solution**: Ensure the `x-api-key` header is included in all requests. #### Invalid or Missing API Key (401) ```json { "success": false, "error": { "code": "AUTH_002", "message": "Invalid or missing API key", "doc_url": "https://docs.sent.dm/errors/AUTH_002" }, "meta": { ... } } ``` **Solution**: * Verify your API key is correct and the `x-api-key` header value is not empty * Check if the key has been revoked * Generate a new key from the dashboard if needed ``` -------------------------------- ### Main Application Setup with Gin Source: https://docs.sent.dm/sdks/go/integrations/gin This snippet shows the main entry point for a Gin application integrating the Sent DM SDK. It covers configuration loading, logger setup, dependency injection, middleware configuration, route definition, and graceful server shutdown. ```go // cmd/api/main.go package main import ( "context" "errors" "fmt" "log/slog" "net/http" "os" "os/signal" "syscall" "time" "github.com/gin-gonic/gin" swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" "sent-gin-service/internal/config" "sent-gin-service/internal/handlers" "sent-gin-service/internal/middleware" "sent-gin-service/internal/service" "sent-gin-service/pkg/sentdm" _ "sent-gin-service/start/swagger" ) // @title Sent DM Gin Service API // @version 1.0 // @description Production-ready Sent DM integration with Gin // @host localhost:8080 // @BasePath /api/v1 // @securityDefinitions.apikey BearerAuth // @in header // @name Authorization func main() { cfg, err := config.Load() if err != nil { fmt.Fprintf(os.Stderr, "Failed to load config: %v\n", err) os.Exit(1) } logger := setupLogger(cfg.Log) logger.Info("starting server", slog.String("addr", cfg.Addr())) if cfg.Log.Level == "debug" { gin.SetMode(gin.DebugMode) } else { gin.SetMode(gin.ReleaseMode) } sentClient, err := sentdm.NewClient(cfg.Sent.APIKey, logger) if err != nil { logger.Error("failed to create sent client", slog.String("error", err.Error())) os.Exit(1) } messageService := service.NewMessageService(sentClient, logger) webhookService := service.NewWebhookService(logger) messageHandler := handlers.NewMessageHandler(messageService) webhookHandler := handlers.NewWebhookHandler(webhookService) rateLimiter := middleware.NewRateLimiter(cfg.RateLimit.RequestsPerSecond, cfg.RateLimit.BurstSize, cfg.RateLimit.TTL) router := gin.New() router.Use(middleware.Recovery(logger)) router.Use(middleware.RequestLogger(logger)) router.Use(middleware.CORS()) router.Use(middleware.ErrorHandler(logger)) router.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"status": "healthy", "timestamp": time.Now().UTC()}) }) router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) webhookHandler.RegisterRoutes(router) apiV1 := router.Group("/api/v1") apiV1.Use(middleware.APIKeyAuth(cfg.Sent.APIKey)) apiV1.Use(rateLimiter.RateLimit()) messageHandler.RegisterRoutes(apiV1) srv := &http.Server{ Addr: cfg.Addr(), Handler: router, ReadTimeout: cfg.Server.ReadTimeout, WriteTimeout: cfg.Server.WriteTimeout, IdleTimeout: cfg.Server.IdleTimeout, } go func() { logger.Info("server listening", slog.String("addr", srv.Addr)) if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { logger.Error("server failed to start", slog.String("error", err.Error())) os.Exit(1) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit logger.Info("shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), cfg.Server.ShutdownTimeout) defer cancel() if err := srv.Shutdown(ctx); err != nil { logger.Error("server forced to shutdown", slog.String("error", err.Error())) os.Exit(1) } logger.Info("server exited gracefully") } func setupLogger(cfg config.LogConfig) *slog.Logger { var level slog.Level switch cfg.Level { case "debug": level = slog.LevelDebug case "warn": level = slog.LevelWarn case "error": level = slog.LevelError default: level = slog.LevelInfo } opts := &slog.HandlerOptions{Level: level} var handler slog.Handler if cfg.Format == "json" { handler = slog.NewJSONHandler(os.Stdout, opts) } else { handler = slog.NewTextHandler(os.Stdout, opts) } return slog.New(handler) } ``` -------------------------------- ### Example Response for Get Message Activities Source: https://docs.sent.dm/llms-full.txt This JSON example demonstrates a successful response for the 'Get message activities' endpoint. It shows a message ID and a list of activities, including SENT, DELIVERED, PROCESSED, and QUEUED statuses with corresponding timestamps and pricing. ```json { "success": true, "data": { "message_id": "8ba7b830-9dad-11d1-80b4-00c04fd430c8", "activities": [ { "status": "DELIVERED", "description": "Message delivered to recipient", "from": "+15551234567", "timestamp": "2026-05-31T15:03:04.5454163+00:00", "price": "0.0450", "active_contact_price": "0.0050" }, { "status": "SENT", "description": "Message sent via SMS", "from": "+15551234567", "timestamp": "2026-05-31T14:58:04.5454934+00:00", "price": "0.0450", "active_contact_price": "0.0050" }, { "status": "PROCESSED", "description": "Message processed and queued for sending", "from": null, "timestamp": "2026-05-31T14:57:04.5454937+00:00", "price": "0.0450", "active_contact_price": "0.0050" }, { "status": "QUEUED", "description": "Message accepted and queued for processing", "from": null, "timestamp": "2026-05-31T14:56:04.5454939+00:00", "price": null, "active_contact_price": null } ] }, "error": null, "meta": { "request_id": "req_7X9zKp2jDw", "timestamp": "2026-05-31T15:28:04.5455102+00:00", "version": "v3" } } ``` -------------------------------- ### Example .env File Configuration Source: https://docs.sent.dm/sdks/go/integrations/echo Provides an example of an .env file for configuring application settings. Ensure sensitive keys like API and webhook secrets are set. ```dotenv PORT=8080 SERVER_READ_TIMEOUT=5s SERVER_WRITE_TIMEOUT=10s ENVIRONMENT=development SENT_DM_API_KEY=your_api_key_here SENT_DM_WEBHOOK_SECRET=your_webhook_secret_here LOG_LEVEL=info LOG_FORMAT=json RATE_LIMIT_RPS=10 ``` -------------------------------- ### cURL Request to Get Contacts Source: https://docs.sent.dm/reference/api/contacts/SentDmServicesEndpointsCustomerAPIv3ContactsGetContactsEndpoint Example of how to make a GET request to the /v3/contacts endpoint using cURL. Includes pagination parameters. ```curl curl -X GET "https://api.sent.dm/v3/contacts?page=1&page_size=20" \ -H "x-api-key: " ``` -------------------------------- ### cURL Request to Get Webhooks Source: https://docs.sent.dm/reference/api/webhooks/SentDmServicesEndpointsCustomerAPIv3WebhooksGetWebhooksEndpoint Example of how to make a GET request to the webhooks endpoint using cURL, including pagination and filtering parameters. ```shell curl -X GET "https://api.sent.dm/v3/webhooks?page=1&page_size=20&is_active=true" \ -H "x-api-key: " ``` -------------------------------- ### Main Application Entry Point Source: https://docs.sent.dm/llms-full.txt This Go code sets up the main application for Sent-DM. It loads configuration, initializes logging, sets up services, configures the Echo web framework with middleware, registers handlers, and manages graceful server startup and shutdown. ```go package main import ( "context" "net/http" "os" "os/signal" "syscall" "time" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/sentdm/sent-dm-go/sent-echo-app/internal/config" "github.com/sentdm/sent-dm-go/sent-echo-app/internal/handler" appmiddleware "github.com/sentdm/sent-dm-go/sent-echo-app/internal/middleware" "github.com/sentdm/sent-dm-go/sent-echo-app/internal/service" appvalidator "github.com/sentdm/sent-dm-go/sent-echo-app/internal/validator" "github.com/sentdm/sent-dm-go/sent-echo-app/pkg/sentclient" "go.uber.org/zap" ) func main() { cfg, err := config.Load() if err != nil { panic(err) } logger, err := config.NewLogger(cfg.Log) if err != nil { panic(err) } defer logger.Sync() sentClient := sentclient.New(cfg.Sent.APIKey, logger) messageService := service.NewMessageService(sentClient, logger) webhookService := service.NewWebhookService(sentClient, logger, cfg.Sent.WebhookSecret) e := echo.New() e.HideBanner = true e.Validator = appvalidator.New() e.HTTPErrorHandler = appmiddleware.ErrorHandler(logger) e.Use(middleware.RequestID()) e.Use(appmiddleware.Logger(logger)) e.Use(middleware.Recover()) e.Use(middleware.CORS()) e.Use(middleware.Secure()) e.Use(middleware.RateLimiter(middleware.NewRateLimiterMemoryStore(cfg.RateLimit.RequestsPerSecond))) handler.NewHealthHandler().Register(e) handler.NewMessageHandler(messageService, logger).Register(e) handler.NewWebhookHandler(webhookService, logger).Register(e) srv := &http.Server{ Addr: ": ``` -------------------------------- ### cURL Request to Get Templates Source: https://docs.sent.dm/reference/api/templates/SentDmServicesEndpointsCustomerAPIv3TemplatesGetTemplatesEndpoint Example of how to make a GET request to the /v3/templates endpoint using cURL. Includes parameters for pagination and search. ```curl curl -X GET "https://api.sent.dm/v3/templates?page=1&page_size=20&search=welcome&status=APPROVED" \ -H "x-api-key: " ``` -------------------------------- ### Main Application Entry Point Source: https://docs.sent.dm/llms-full.txt This Go program serves as the main entry point for the Sent DM Gin Service. It handles configuration loading, logger setup, dependency injection, route registration, and graceful server shutdown. ```go package main import ( "context" "errors" "fmt" "log/slog" "net/http" "os" "os/signal" "syscall" "time" "github.com/gin-gonic/gin" swaggerFiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" "sent-gin-service/internal/config" "sent-gin-service/internal/handlers" "sent-gin-service/internal/middleware" "sent-gin-service/internal/service" "sent-gin-service/pkg/sentdm" _ "sent-gin-service/start/swagger" ) // @title Sent DM Gin Service API // @version 1.0 // @description Production-ready Sent DM integration with Gin // @host localhost:8080 // @BasePath /api/v1 // @securitydefinitions.apikey BearerAuth // @in header // @name Authorization func main() { cfg, err := config.Load() if err != nil { fmt.Fprintf(os.Stderr, "Failed to load config: %v\n", err) os.Exit(1) } logger := setupLogger(cfg.Log) logger.Info("starting server", slog.String("addr", cfg.Addr())) if cfg.Log.Level == "debug" { gin.SetMode(gin.DebugMode) } else { gin.SetMode(gin.ReleaseMode) } sentClient, err := sentdm.NewClient(cfg.Sent.APIKey, logger) if err != nil { logger.Error("failed to create sent client", slog.String("error", err.Error())) os.Exit(1) } messageService := service.NewMessageService(sentClient, logger) webhookService := service.NewWebhookService(logger) messageHandler := handlers.NewMessageHandler(messageService) webhookHandler := handlers.NewWebhookHandler(webhookService) rateLimiter := middleware.NewRateLimiter(cfg.RateLimit.RequestsPerSecond, cfg.RateLimit.BurstSize, cfg.RateLimit.TTL) router := gin.New() router.Use(middleware.Recovery(logger)) router.Use(middleware.RequestLogger(logger)) router.Use(middleware.CORS()) router.Use(middleware.ErrorHandler(logger)) router.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"status": "healthy", "timestamp": time.Now().UTC()}) }) router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) webhookHandler.RegisterRoutes(router) apiV1 := router.Group("/api/v1") apiV1.Use(middleware.APIKeyAuth(cfg.Sent.APIKey)) apiV1.Use(rateLimiter.RateLimit()) messageHandler.RegisterRoutes(apiV1) srv := &http.Server{ Addr: cfg.Addr(), Handler: router, ReadTimeout: cfg.Server.ReadTimeout, WriteTimeout: cfg.Server.WriteTimeout, IdleTimeout: cfg.Server.IdleTimeout, } go func() { logger.Info("server listening", slog.String("addr", srv.Addr)) if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { logger.Error("server failed to start", slog.String("error", err.Error())) os.Exit(1) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit logger.Info("shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), cfg.Server.ShutdownTimeout) defer cancel() if err := srv.Shutdown(ctx); err != nil { logger.Error("server forced to shutdown", slog.String("error", err.Error())) os.Exit(1) } logger.Info("server exited gracefully") } func setupLogger(cfg config.LogConfig) *slog.Logger { var level slog.Level switch cfg.Level { case "debug": level = slog.LevelDebug case "warn": level = slog.LevelWarn case "error": level = slog.LevelError default: level = slog.LevelInfo } opts := &slog.HandlerOptions{Level: level} var handler slog.Handler if cfg.Format == "json" { handler = slog.NewJSONHandler(os.Stdout, opts) } else { handler = slog.NewTextHandler(os.Stdout, opts) } return slog.New(handler) } ``` -------------------------------- ### Example Successful Account Retrieval Response Source: https://docs.sent.dm/llms-full.txt An example of a successful JSON response for the GET /v3/me endpoint, detailing a 'profile' type account with its associated channels and settings. ```json { "success": true, "data": { "type": "profile", "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "organization_id": "d290f1ee-6c54-4b01-90e6-d701748f0851", "name": "Marketing", "short_name": "MKT", "email": "marketing@acme.com", "icon": "https://cdn.sent.dm/icons/marketing.png", "description": "Marketing department sender profile", "created_at": "2025-01-20T14:00:00+00:00", "channels": { "sms": { "configured": true, "phone_number": "+14155550100" }, "whatsapp": { "configured": true, "phone_number": "+14155550100", "business_name": "Acme Corporation" }, "rcs": { "configured": false, "phone_number": "+14155550100" } }, "status": "approved", "settings": { "allow_contact_sharing": true, "allow_template_sharing": true, "inherit_contacts": true, "inherit_templates": false, "inherit_tcr_brand": true, "inherit_tcr_campaign": false, "billing_model": "organization" }, "profiles": [] }, "error": null, "meta": { "request_id": "req_7X9zKp2jDw", "timestamp": "2026-05-31T15:28:04.6319351+00:00", "version": "v3" } } ``` -------------------------------- ### Dockerfile Example Source: https://docs.sent.dm/llms-full.txt A basic Dockerfile for setting up a SentDM application environment. This snippet is a placeholder and requires specific implementation details. ```dockerfile FROM ruby:3.1 WORKDIR /app COPY Gemfile Gemfile.lock ./ RUN bundle install COPY . . EXPOSE 3000 CMD ["bundle", "exec", "rackup", "-o", "0.0.0.0"] ``` -------------------------------- ### Get User by ID - cURL Example Source: https://docs.sent.dm/reference/api/users/SentDmServicesEndpointsCustomerAPIv3UsersGetUserEndpoint Example of how to retrieve a user by their ID using cURL. Ensure you replace 'string' with a valid user ID and provide your API key. ```cURL curl -X GET "https://api.sent.dm/v3/users/string" \ -H "x-api-key: " ``` -------------------------------- ### Main FastAPI Application Setup Source: https://docs.sent.dm/llms-full.txt Creates and configures the main FastAPI application instance, including middleware, exception handlers, and router inclusions. This is the entry point for the application. ```python import logging from fastapi import FastAPI from slowapi import Limiter from slowapi.errors import RateLimitExceeded from slowapi.middleware import SlowAPIMiddleware from app.config import get_settings from app.lifespan import lifespan from app.middleware import RequestIdMiddleware, LoggingMiddleware from app.routers import messages, webhooks, health logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", ) def create_application() -> FastAPI: settings = get_settings() app = FastAPI( title=settings.app_name, version=settings.app_version, description="FastAPI integration with Sent DM for messaging", lifespan=lifespan, docs_url="/docs" if settings.debug else None, redoc_url="/redoc" if settings.debug else None, ) app.add_middleware(RequestIdMiddleware) app.add_middleware(LoggingMiddleware) limiter = Limiter(key_func=lambda: "global") app.state.limiter = limiter app.add_middleware(SlowAPIMiddleware) register_exception_handlers(app) app.include_router(health.router) app.include_router(messages.router) app.include_router(webhooks.router) return app app = create_application() if __name__ == "__main__": import uvicorn uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=get_settings().debug) ``` -------------------------------- ### Manage Contacts Source: https://docs.sent.dm/sdks/go Provides examples for creating, listing, getting, updating, and deleting contacts using the Go SDK. ```go // Create a contact response, err := client.Contacts.Create(ctx, sentdm.ContactCreateParams{ PhoneNumber: "+1234567890", }) if err != nil { log.Fatal(err) } fmt.Printf("Contact ID: %s\n", response.Data.ID) // List contacts page, err := client.Contacts.List(ctx, sentdm.ContactListParams{ Page: 1, PageSize: 100, }) // Get a contact contact, err := client.Contacts.Get(ctx, "contact-uuid") // Update a contact response, err = client.Contacts.Update(ctx, "contact-uuid", sentdm.ContactUpdateParams{ PhoneNumber: sentdm.String("+1987654321"), }) // Delete a contact err = client.Contacts.Delete(ctx, "contact-uuid") ``` -------------------------------- ### Successful Response - Get Profiles Source: https://docs.sent.dm/reference/api/profiles/SentDmServicesEndpointsCustomerAPIv3ProfilesGetProfilesEndpoint This is an example of a successful response when retrieving sender profiles. It includes a list of profiles with their associated details. ```json { "success": true, "data": { "profiles": [ { "id": "660e8400-e29b-41d4-a716-446655440001", "organization_id": "550e8400-e29b-41d4-a716-446655440000", "name": "Marketing Team", "email": "team@acme.com", "icon": "https://example.com/marketing-icon.png", "description": "Marketing department sender profile", "short_name": "MKT", "status": "approved", "created_at": "2026-02-28T15:28:05.1269318+00:00", "updated_at": "2026-05-26T15:28:05.1269324+00:00", "allow_contact_sharing": true, "allow_template_sharing": false, "inherit_contacts": true, "inherit_templates": false, "inherit_tcr_brand": false, "inherit_tcr_campaign": false, "billing_model": "profile", "sending_phone_number_profile_id": null, "sending_whatsapp_number_profile_id": null, "sending_phone_number": null, "whatsapp_phone_number": null, "allow_number_change_during_onboarding": null, "waba_id": null, "billing_contact": null, "brand": { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "tcr_brand_id": null, "status": null, "identity_status": null, "universal_ein": null, "csp_id": null, "submitted_to_tcr": false, "submitted_at": null, "is_inherited": false, "created_at": "2026-02-28T15:28:05.1269329+00:00", "updated_at": null, "contact": { "name": "John Smith", "business_name": "Acme Corp", "role": null, "phone": null, "email": "john@acmecorp.com", "phone_country_code": null }, "business": { "legal_name": "Acme Corporation LLC", "tax_id": null, "tax_id_type": null, "entity_type": null, "street": null, "city": null, "state": null, "postal_code": null, "country": "US", "url": null, "country_of_registration": null }, "compliance": { "vertical": "PROFESSIONAL", "brand_relationship": "SMALL_ACCOUNT", "primary_use_case": null, "expected_messaging_volume": null, "is_tcr_application": true, "phone_number_prefix": null, "destination_countries": [], "notes": null } } } ] }, "error": null, "meta": { "request_id": "req_7X9zKp2jDw", "timestamp": "2026-05-31T15:28:05.1269582+00:00", "version": "v3" } } ``` -------------------------------- ### Manage Templates Source: https://docs.sent.dm/sdks/go Demonstrates how to list and retrieve templates using the Go SDK. ```go // List templates templates, err := client.Templates.List(ctx, sentdm.TemplateListParams{}) if err != nil { log.Fatal(err) } for _, template := range templates.Data.Templates { fmt.Printf("%s (%s): %s\n", template.Name, template.Status, template.ID) } // Get a template template, err := client.Templates.Get(ctx, "template-uuid") fmt.Printf("Name: %s\n", template.Name) fmt.Printf("Status: %s\n", template.Status) ``` -------------------------------- ### Vitest Setup File Source: https://docs.sent.dm/llms-full.txt Sets up the testing environment for Vitest, including importing testing-library extensions and mocking Next.js cache functions and server-only module. ```typescript // vitest.setup.ts import '@testing-library/jest-dom/vitest'; import { vi } from 'vitest'; vi.mock('next/cache', () => ({ revalidatePath: vi.fn(), revalidateTag: vi.fn(), unstable_cache: (fn: Function) => fn, })); vi.mock('server-only', () => ({})); ``` -------------------------------- ### Manage Contacts with PHP SDK Source: https://docs.sent.dm/sdks/php Provides examples for creating, listing, getting, updating, and deleting contacts using the SentDM PHP SDK. ```php // Create a contact $result = $client->contacts->create([ 'phoneNumber' => '+1234567890' ]); var_dump($result->data->id); // List contacts $result = $client->contacts->list(['page' => 1, 'page_size' => 100]); foreach ($result->data->contacts as $contact) { echo $contact->phoneNumber . " - " . implode(', ', $contact->availableChannels) . "\n"; } // Get a contact $result = $client->contacts->get('contact-uuid'); // Update a contact $result = $client->contacts->update('contact-uuid', [ 'phoneNumber' => '+1987654321' ]); // Delete a contact $client->contacts->delete('contact-uuid'); ``` -------------------------------- ### Successful Response - Get Webhooks Source: https://docs.sent.dm/reference/api/webhooks/SentDmServicesEndpointsCustomerAPIv3WebhooksGetWebhooksEndpoint Example of a successful JSON response when retrieving a list of webhooks. Includes webhook details and pagination metadata. ```json { "success": true, "data": { "webhooks": [ { "id": "d4f5a6b7-c8d9-4e0f-a1b2-c3d4e5f6a7b8", "display_name": "Order Notifications", "endpoint_url": "https://example.com/webhooks/orders", "signing_secret": null, "is_active": true, "event_types": [ "message", "templates" ], "event_filters": null, "retry_count": 3, "timeout_seconds": 30, "last_delivery_attempt_at": null, "last_successful_delivery_at": null, "consecutive_failures": 0, "created_at": "2026-01-15T10:30:00+00:00", "updated_at": null } ], "pagination": { "page": 1, "page_size": 20, "total_count": 1, "total_pages": 1, "has_more": false, "cursors": null } }, "error": null, "meta": { "request_id": "req_7X9zKp2jDw", "timestamp": "2026-05-31T15:28:26.8089945+00:00", "version": "v3" } } ``` -------------------------------- ### Example: Show Deliverability Stats Source: https://docs.sent.dm/start/llm-docs/mcp-server Example of how to instruct an agent to retrieve deliverability statistics for a specified time range. ```natural_language Show me deliverability stats for the last 7 days ``` -------------------------------- ### Successful Response - Get Templates Source: https://docs.sent.dm/reference/api/templates/SentDmServicesEndpointsCustomerAPIv3TemplatesGetTemplatesEndpoint Example of a successful JSON response when retrieving a list of templates. Includes template data and pagination metadata. ```json { "success": true, "data": { "templates": [ { "id": "7ba7b820-9dad-11d1-80b4-00c04fd430c8", "name": "Welcome Message", "category": "MARKETING", "language": "en_US", "status": "APPROVED", "channels": [ "sms", "whatsapp" ], "variables": [ "name", "company" ], "created_at": "2026-05-01T15:28:26.9049647+00:00", "updated_at": "2026-05-16T15:28:26.9049651+00:00", "is_published": true } ], "pagination": { "page": 1, "page_size": 20, "total_count": 1, "total_pages": 1, "has_more": false, "cursors": null } }, "error": null, "meta": { "request_id": "req_7X9zKp2jDw", "timestamp": "2026-05-31T15:28:26.9050591+00:00", "version": "v3" } } ``` -------------------------------- ### Example error response for GET /v3/me Source: https://docs.sent.dm/llms-full.txt This JSON illustrates an error response when the API key is invalid or missing, resulting in a 401 Unauthorized status. ```json { "success": false, "error": { "code": "INTERNAL_001", "message": "An unexpected error occurred while retrieving account information. Please try again later.", "details": null, "doc_url": "https://docs.sent.dm/reference/api/error-catalog" }, "meta": { "request_id": "req_7X9zKp2jDw", "timestamp": "2026-05-31T15:28:04.6319385+00:00", "version": "v3" } } ``` -------------------------------- ### Initialize Value Objects with PHP Source: https://docs.sent.dm/sdks/php Demonstrates the recommended way to initialize value objects using static 'with' constructors and named parameters, and also shows the builder pattern. ```php use SentDM\Models\TemplateDefinition; $definition = TemplateDefinition::with( body: [...], header: [...], ); ``` ```php $definition = (new TemplateDefinition)->withBody([...]); ``` -------------------------------- ### Get Webhook Event Types (Python) Source: https://docs.sent.dm/reference/api/webhooks/SentDmServicesEndpointsCustomerAPIv3WebhooksGetWebhookEventTypesEndpoint A Python example for fetching webhook event types. Replace 'YOUR_API_KEY' with your actual API key before running. ```python import requests api_key = "YOUR_API_KEY" url = "https://api.sent.dm/v3/webhooks/event-types" headers = { "x-api-key": api_key } response = requests.get(url, headers=headers) print(f"Status Code: {response.status_code}") print(f"Response JSON: {response.json()}") ``` -------------------------------- ### Get Webhook Events (cURL) Source: https://docs.sent.dm/reference/api/webhooks/SentDmServicesEndpointsCustomerAPIv3WebhooksGetWebhookEventsEndpoint Example of how to retrieve webhook events using cURL. Ensure to replace the placeholder API key and webhook ID. ```curl curl -X GET "https://api.sent.dm/v3/webhooks/d4f5a6b7-c8d9-4e0f-a1b2-c3d4e5f6a7b8/events?page=1&page_size=20" \ -H "x-api-key: " ``` -------------------------------- ### Get User by ID - Error Response (No Access) Source: https://docs.sent.dm/reference/api/users/SentDmServicesEndpointsCustomerAPIv3UsersGetUserEndpoint Example of an error response when the user does not have access to the organization or profile. The 'error' object provides details. ```JSON { "success": false, "data": null, "error": { "code": "AUTH_004", "message": "You do not have access to this organization or profile", "details": null, "doc_url": "https://docs.sent.dm/reference/api/authentication" }, "meta": { "request_id": "req_7X9zKp2jDw", "timestamp": "2026-05-31T15:28:04.9249379+00:00", "version": "v3" } } ``` -------------------------------- ### Go: Sandbox vs. Idempotency Source: https://docs.sent.dm/reference/api/idempotency Illustrates using sandbox mode for validation and then a production request with an idempotency key for safe retries. ```go // Sandbox mode without idempotency - for initial validation client.Request("POST", "/v3/messages", map[string]interface{}{ "sandbox": true, "phone_number": "+1234567890", "template_id": "template-id", }, "") // Production request with idempotency - safe to retry client.Request("POST", "/v3/messages", map[string]interface{}{ "phone_number": "+1234567890", "template_id": "template-id", }, "msg-123") ``` -------------------------------- ### Get User by ID - Successful Response Source: https://docs.sent.dm/reference/api/users/SentDmServicesEndpointsCustomerAPIv3UsersGetUserEndpoint Example of a successful response when retrieving user details. The 'data' object contains the user's information. ```JSON { "success": true, "data": { "id": "880e8400-e29b-41d4-a716-446655440003", "email": "admin@acme.com", "name": "John Admin", "role": "admin", "status": "active", "invited_at": "2025-11-30T15:28:04.9248166+00:00", "last_login_at": "2026-05-31T13:28:04.9248719+00:00", "created_at": "2025-11-30T15:28:04.9249012+00:00", "updated_at": "2026-05-30T15:28:04.9249184+00:00" }, "error": null, "meta": { "request_id": "req_7X9zKp2jDw", "timestamp": "2026-05-31T15:28:04.9249352+00:00", "version": "v3" } } ``` -------------------------------- ### Environment Variables for Configuration Source: https://docs.sent.dm/llms-full.txt Example `.env.example` file demonstrating the environment variables used to configure the Gin application, covering server, Sent DM, logging, and rate limiting settings. ```bash # .env.example SERVER_PORT=8080 SERVER_HOST=0.0.0.0 SERVER_READ_TIMEOUT=30s SERVER_WRITE_TIMEOUT=30s SENT_API_KEY=your_api_key_here SENT_DM_WEBHOOK_SECRET=your_webhook_secret_here LOG_LEVEL=info LOG_FORMAT=json RATE_LIMIT_REQUESTS_PER_SECOND=10 RATE_LIMIT_BURST_SIZE=20 ``` -------------------------------- ### Initialize the client Source: https://docs.sent.dm/sdks/csharp Demonstrates how to initialize the SentClient, either by using the SENT_DM_API_KEY environment variable or by explicit configuration. ```APIDOC ```csharp using Sentdm; // Configured using the SENT_DM_API_KEY environment variable SentClient client = new(); ``` ``` -------------------------------- ### Send Message using Sentdm Python SDK Source: https://docs.sent.dm/start/reference-guides/faq Example of sending a message using the Sentdm Python SDK. Ensure the SDK is installed and your API key is configured. ```python from sentdm import SentClient client = SentClient("YOUR_API_KEY") response = client.messages.create( to="+15551234567", from_="+15557654321", text="Hello from Sent!" ) print(response.id) ```