{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"Getting Started: Borrower Campaigns with Bulk Sender","siteUrl":"https://docs.peachfinance.com","description":"API and product documentation for Peach Finance, a lending-as-a-service platform.","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"getting-started-borrower-campaigns-with-bulk-sender","__idx":0},"children":["Getting Started: Borrower Campaigns with Bulk Sender"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This tutorial will guide you through creating your first borrower campaign with bulk sender functionality. Bulk senders allow you to automatically send communications (emails, text messages, etc.) to borrowers based on query results from Redash."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Borrower campaigns with bulk senders enable you to:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Query your borrower data using Redash"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Automatically send communications to borrowers matching your query criteria"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Schedule campaigns to run automatically on a recurring basis"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Track campaign execution and results"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The workflow consists of three main components:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Redash Query"]},": Defines which borrowers to target"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Bulk Sender"]},": Configures what message to send and how"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Campaign"]},": Ties everything together and optionally schedules execution"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"prerequisites","__idx":2},"children":["Prerequisites"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before you begin, ensure you have:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Access to Redash with a query that returns borrower data"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A Redash API key (found at ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://{YOUR_REDASH_DOMAIN}/users/me"]},")"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-1-create-a-redash-query","__idx":3},"children":["Step 1: Create a Redash Query"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Your Redash query must return at least a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["borrowerId"]}," column. You can use either:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Public IDs (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BO-XXXX-XXXX"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Internal database IDs (integers)"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"example-query","__idx":4},"children":["Example Query"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Specify a SQL query targeting the borrowers you care about:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"sql","header":{"controls":{"copy":{}}},"source":"select distinct \n  lp.person_id as \"borrowerId\",\n  l.id as \"loanId\"\nfrom\n  loans l\njoin loan_people lp on lp.loan_id = l.id\njoin people p on lp.person_id = p.id\nwhere\n  l.status = 'Active' \n  and {other properties of loans or borrowers you care about};\n","lang":"sql"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Important"]},": The column must be named exactly ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["borrowerId"]}," (case-sensitive)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"query-result-format","__idx":5},"children":["Query Result Format"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For basic bulk sending, your query result could look like:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"borrowerId,loanId\n100,200\n103,205\n...\n"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"custom-context-variables","__idx":6},"children":["Custom Context Variables"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can pass custom data to your message templates by prefixing columns with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context."]},". For example:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"sql","header":{"controls":{"copy":{}}},"source":"SELECT \n    b.id AS \"borrowerId\",\n    l.id AS \"loanId\",\n    l.total_amount AS \"context.loanAmount\",\n    l.due_date AS \"context.dueDate\"\nFROM borrowers b\nJOIN loans l ON l.borrower_id = b.id\nWHERE l.status = 'overdue'\n","lang":"sql"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This will make ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loanAmount"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dueDate"]}," available in your message templates via the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context"]}," object."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-2-create-a-bulk-sender","__idx":7},"children":["Step 2: Create a Bulk Sender"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A bulk sender defines:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Interaction Subject"]},": The type of message (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentDueDateReminder"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loanOverdueFirstNotice"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Interaction Theme"]},": The category of interaction (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["opsServicing"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["collections"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Interaction Channel"]},": The delivery method (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["email"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["text"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["mail"]},")"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Note"]},": Only ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["mail"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["text"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["email"]}," channels are compatible with the campaigns system."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"example-create-a-payment-reminder-bulk-sender","__idx":8},"children":["Example: Create a Payment Reminder Bulk Sender"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"POST /api/campaign-workers/bulk-senders\nContent-Type: application/json\n\n{\n  \"interactionSubject\": \"paymentDueDateReminder\",\n  \"interactionTheme\": \"opsServicing\",\n  \"interactionChannel\": \"email\",\n}\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"response","__idx":9},"children":["Response"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"data\": {\n    \"id\": \"BS-XXXX-XXXX\",\n    \"interactionSubject\": \"paymentDueDateReminder\",\n    \"interactionTheme\": \"opsServicing\",\n    \"interactionChannel\": \"email\",\n    \"createdAt\": \"2024-01-15T10:30:00Z\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Save the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]}," field (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BS-XXXX-XXXX"]},") - you'll need it when creating the campaign."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"available-interaction-subjects","__idx":10},"children":["Available Interaction Subjects"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Some common interaction subjects that work well with bulk senders:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentDueDateReminder"]}," - Remind borrowers of upcoming payments"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loanOverdueFirstNotice"]}," - First notice for overdue loans"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loanOverdueSecondNotice"]}," - Second notice for overdue loans"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["autopayPaymentReminder"]}," - Remind borrowers of upcoming autopay payments"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["autopayEnableReminder"]}," - Encourage borrowers to enable autopay"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loginFirstPaymentReminder"]}," - Remind borrowers who haven't logged in about their first payment"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardExpiresReminder"]}," - Notify borrowers about expiring payment cards"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each subject has specific query requirements and automatically calculated context variables."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-3-create-a-campaign","__idx":11},"children":["Step 3: Create a Campaign"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Now you'll create a campaign that ties your Redash query to your bulk sender."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"example-create-a-campaign","__idx":12},"children":["Example: Create a Campaign"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"POST /api/campaigns\nContent-Type: application/json\n\n{\n  \"redashQueryUrl\": \"https://your-redash-domain.com/queries/123\",\n  \"redashApiKey\": \"your-redash-api-key\",\n  \"bulkSenderId\": \"BS-XXXX-XXXX\",\n  \"externalId\": \"weekly-payment-reminders\",\n  \"schedule\": \"P P * * mon\"\n}\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"campaign-parameters","__idx":13},"children":["Campaign Parameters"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redashQueryUrl"]}]},": The full URL to your Redash query (format: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://{DOMAIN}/queries/{QUERY_ID}"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redashApiKey"]}]},": Your Redash API key"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["bulkSenderId"]}]},": The ID of the bulk sender created in Step 2"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["externalId"]}]},": (Optional) Your own identifier for this campaign"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["schedule"]}]},": (Optional) Cron schedule for automatic execution"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"schedule-format","__idx":14},"children":["Schedule Format"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The schedule uses \"Peachy crontab\" format where ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["P"]}," means \"Peach decides\":"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Minute and hour fields must be ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["P"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Day, month, and day-of-week can be standard cron values"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Examples:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["P P * * mon"]}," - Every Monday"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["P P 1,15 * *"]}," - 1st and 15th of every month"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["P P * * wed"]}," - Every Wednesday"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["P P * 10 *"]}," - Every day in October"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["schedule"]}," is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},", the campaign must be run manually."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"response-1","__idx":15},"children":["Response"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"data\": {\n    \"id\": \"BC-XXXX-XXXX\",\n    \"redashQueryUrl\": \"https://your-redash-domain.com/queries/123\",\n    \"bulkSenderId\": \"BS-XXXX-XXXX\",\n    \"externalId\": \"weekly-payment-reminders\",\n    \"schedule\": \"P P * * mon\",\n    \"createdAt\": \"2024-01-15T10:35:00Z\"\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-4-run-a-campaign","__idx":16},"children":["Step 4: Run a Campaign"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you didn't set a schedule, or want to run the campaign immediately, you can trigger it manually."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"manual-campaign-run","__idx":17},"children":["Manual Campaign Run"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"POST /api/campaigns/BC-XXXX-XXXX/runs\nContent-Type: application/json\n\n{}\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"override-query-results-optional","__idx":18},"children":["Override Query Results (Optional)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For testing, you can override the Redash query with custom data:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"POST /api/campaigns/BC-XXXX-XXXX/runs\nContent-Type: application/json\n\n{\n  \"queryResultsOverride\": [\n    {\n      \"borrowerId\": \"BO-YYYY-YYYY\",\n      \"loanId\": \"LO-ZZZZ-ZZZZ\"\n    },\n    {\n      \"borrowerId\": \"BO-AAAA-AAAA\",\n      \"loanId\": \"LO-BBBB-BBBB\"\n    }\n  ]\n}\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"response-2","__idx":19},"children":["Response"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"data\": {\n    \"id\": \"RN-XXXX-XXXX\",\n    \"borrowerCampaignId\": \"BC-XXXX-XXXX\",\n    \"status\": \"initializing\",\n    \"availableFiles\": []\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-5-monitor-campaign-runs","__idx":20},"children":["Step 5: Monitor Campaign Runs"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Check the status of your campaign run:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"GET /api/campaigns/BC-XXXX-XXXX/runs/RN-XXXX-XXXX\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"run-statuses","__idx":21},"children":["Run Statuses"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["initializing"]}," - Campaign run is being set up"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["processing"]}," - Campaign is actively running"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["success"]}," - Campaign completed successfully"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["failed"]}," - Campaign encountered an error"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"download-campaign-results","__idx":22},"children":["Download Campaign Results"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Once a campaign run completes, you can download various files:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"GET /api/campaigns/BC-XXXX-XXXX/runs/RN-XXXX-XXXX/download?file=all\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Available files:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["query_results.csv"]}," - Raw query results from Redash"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["campaign_input.json"]}," - Parsed query results used as input"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["contacts.csv"]}," - Exported contacts (if using contact exporter)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["log.txt"]}," - Execution log"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["file=all"]}," to download all files as a ZIP, or specify a specific file."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"best-practices","__idx":23},"children":["Best Practices"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"1-query-optimization","__idx":24},"children":["1. Query Optimization"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Keep your queries focused and efficient"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use appropriate WHERE clauses to limit results"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Consider adding indexes on frequently queried columns"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"2-testing","__idx":25},"children":["2. Testing"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Always test with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["queryResultsOverride"]}," first using a small dataset"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Verify message templates work correctly with your context variables",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Campaign bulk send messages are sent with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["strictUndefined: true"]}," meaning there can be NO undefined variables or the send will fail. (This is not the default setting when using the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/send"]}," endpoint.)"]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Check campaign run logs for any errors.",{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["It's important to ",{"$$mdtype":"Tag","name":"em","attributes":{},"children":["check the logs not just the status"]}," of the campaign run. This is because some or all of the message sends might fail even while the campaign run itself is considered a success."]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"3-scheduling","__idx":26},"children":["3. Scheduling"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Start with manual runs to verify everything works"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Note that the schedule syntax is ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"https://en.wikipedia.org/wiki/Cron"},"children":["\"crontab\" like"]},". You can specify a crontab except the first two parts must be ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["P P"]}," this indicates that the specific time of execution on the given day is at Peach's discretion."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"4-context-variables","__idx":27},"children":["4. Context Variables"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.*"]}," columns in your query to pass custom data to templates"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Be aware that some interaction subjects automatically calculate context variables"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Ensure all required context variables are present or calculated"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"troubleshooting","__idx":28},"children":["Troubleshooting"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"campaign-run-fails","__idx":29},"children":["Campaign Run Fails"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Check the campaign run status and logs:",{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"GET /api/campaigns/{campaignId}/runs/{runId}\nGET /api/campaigns/{campaignId}/runs/{runId}/download?file=log.txt\n","lang":"bash"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"messages-not-sending","__idx":30},"children":["Messages Not Sending"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Verify the bulk sender configuration:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Check that ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["interactionSubject"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["interactionTheme"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["interactionChannel"]}," are valid"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Ensure message templates exist for the specified subject/theme/channel combination"]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Check borrower eligibility:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Borrowers must have valid contact information for the specified channel"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Compliance checks may prevent sending (Do Not Interact, frequency limits, etc.)"]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"query-results-issues","__idx":31},"children":["Query Results Issues"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Verify your Redash query:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Test the query directly in Redash"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Ensure column names match exactly (case-sensitive)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Check that IDs are valid (either public IDs or internal integer IDs)"]}]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Check query result format:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Minimum required: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["borrowerId"]}," column"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Additional columns depend on the interaction subject"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.*"]}," prefix for custom context variables"]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"next-steps","__idx":32},"children":["Next steps"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/communications/editing-templates"},"children":["Editing Templates"]}]}," — Customize the templates used by bulk campaigns and one-off sends."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/communications"},"children":["Communications overview"]}]}," — Index of communications channels and tools."]}]}]},"headings":[{"value":"Getting Started: Borrower Campaigns with Bulk Sender","id":"getting-started-borrower-campaigns-with-bulk-sender","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"Prerequisites","id":"prerequisites","depth":2},{"value":"Step 1: Create a Redash Query","id":"step-1-create-a-redash-query","depth":2},{"value":"Example Query","id":"example-query","depth":3},{"value":"Query Result Format","id":"query-result-format","depth":3},{"value":"Custom Context Variables","id":"custom-context-variables","depth":3},{"value":"Step 2: Create a Bulk Sender","id":"step-2-create-a-bulk-sender","depth":2},{"value":"Example: Create a Payment Reminder Bulk Sender","id":"example-create-a-payment-reminder-bulk-sender","depth":3},{"value":"Response","id":"response","depth":3},{"value":"Available Interaction Subjects","id":"available-interaction-subjects","depth":3},{"value":"Step 3: Create a Campaign","id":"step-3-create-a-campaign","depth":2},{"value":"Example: Create a Campaign","id":"example-create-a-campaign","depth":3},{"value":"Campaign Parameters","id":"campaign-parameters","depth":3},{"value":"Schedule Format","id":"schedule-format","depth":3},{"value":"Response","id":"response-1","depth":3},{"value":"Step 4: Run a Campaign","id":"step-4-run-a-campaign","depth":2},{"value":"Manual Campaign Run","id":"manual-campaign-run","depth":3},{"value":"Override Query Results (Optional)","id":"override-query-results-optional","depth":3},{"value":"Response","id":"response-2","depth":3},{"value":"Step 5: Monitor Campaign Runs","id":"step-5-monitor-campaign-runs","depth":2},{"value":"Run Statuses","id":"run-statuses","depth":3},{"value":"Download Campaign Results","id":"download-campaign-results","depth":3},{"value":"Best Practices","id":"best-practices","depth":2},{"value":"1. Query Optimization","id":"1-query-optimization","depth":3},{"value":"2. Testing","id":"2-testing","depth":3},{"value":"3. Scheduling","id":"3-scheduling","depth":3},{"value":"4. Context Variables","id":"4-context-variables","depth":3},{"value":"Troubleshooting","id":"troubleshooting","depth":2},{"value":"Campaign Run Fails","id":"campaign-run-fails","depth":3},{"value":"Messages Not Sending","id":"messages-not-sending","depth":3},{"value":"Query Results Issues","id":"query-results-issues","depth":3},{"value":"Next steps","id":"next-steps","depth":2}],"frontmatter":{"seo":{"title":"Getting Started: Borrower Campaigns with Bulk Sender"}},"lastModified":"2026-05-01T14:33:55.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/communications/bulk-sender","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}