# Delivery methods Source: https://developers.momogood.com/data-hub/delivery-methods Reports can be automatically delivered to one or more of the following destinations: * **Amazon S3** (AWS) * **Google Cloud Storage** (GCP) * **SFTP** (Secure File Transfer Protocol) * **Email** (Delivered as an attachment) If you have a delivery method you'd like to see added please reach out to your Customer Success Manager or [support@tatango.com](mailto:support@tatango.com). # Introduction Source: https://developers.momogood.com/data-hub/introduction Introduction to the momoGood Messaging Data Hub ## What is the momoGood Messaging Data Hub? The momoGood Messaging Data Hub (formerly Tatango Data Hub) offers Automated Reports that provide powerful insights into your campaigns and subscriber activity. These reports are designed to be ingested into your data warehouse, imported into your CRM, or used for ad-hoc analysis, ensuring your team has the data they need to monitor campaign performance, track subscriber engagement, and make data-driven decisions. ## How to Request and Enable Automated Reports: To enable any of the automated reports listed below, please reach out to your momoGood Customer Success Manager or [support@tatango.com](mailto:support@tatango.com). Ensure you provide the following information: 1. **Report Name**: Specify the report(s) you'd like to enable 2. **Frequency**: Indicate how often you'd like to receive the report (e.g., daily, weekly, monthly). 3. **Delivery Method**: Choose a delivery destination (AWS S3, GCP, SFTP, or email). Additional delivery destinations may be available upon request. 4. **Custom Fields**: Mention any additional fields from your list you'd like included in the report. Automated reports are available upon request. Let your Customer Success Manager know how we can help streamline your reporting needs! ## Coming soon — programmatic HTTP API access Today, Data Hub reports and their export destinations (AWS S3, GCP, SFTP, email) are configured inside the momoGood Messaging app — you pick the report, frequency, fields, and delivery method from your account settings, and the scheduled export runs from there. **Coming soon:** A programmatic HTTP API for Data Hub, authenticated via OAuth 2.0. You'll be able to list available reports, request on-demand exports, configure delivery destinations, and pull report data directly from your own services — no in-app round-trip required. Until then, use the in-app workflow described above. Contact your Customer Success Manager or [support@tatango.com](mailto:support@tatango.com) to be notified when the API ships. ## Example Use Case A nonprofit organization wants to track communication data in Salesforce. They log messages sent as activity records in Salesforce using the data provided by our Recipients Report. Each record from the report is logged as an activity record on each contact record in Salesforce. In order to accurately do so they add Salesforce Contact ID (bbcrm\_cons\_id) as a custom field on their momoGood Messaging list and upload each subscriber's constituent ID in their initial upload. The nonprofit organization consumes our Recipients Report on a daily basis to an AWS S3 bucket hosted by them. From there, they have a job that runs daily to pick up the .csv file, loop through each record, and create the activity records in Salesforce on each contact. This allows them to have a comprehensive view of texts that their contacts have received in Salesforce. # Active subscribers Source: https://developers.momogood.com/data-hub/reports/active-subscribers **Description**: The Active Subscribers Report provides a comprehensive list of all unique, actively subscribed phone numbers across every list in your account. This report is designed to help organizations—especially those with large or complex list structures—easily identify their current subscriber base. By consolidating active subscriptions into a single view, users can quickly confirm who is eligible to receive messages, streamline list management, and ensure campaigns are reaching the intended audience. **Frequency**: Daily/Weekly/Monthly **Output**: .csv file **Scope**: Includes data from all lists on the account **Customization**: Users can request to append subscriber-level custom fields to the report, such as CRM IDs (e.g., cons\_id from Blackbaud Luminate Online). These custom fields must be pre-configured within the list in your momoGood Messaging account to appear in the report. **Fields**: * `phone_number`: The phone number of the subscriber who replied. # All replies report Source: https://developers.momogood.com/data-hub/reports/all-replies-report **Description**: The All Replies Report provides a detailed list of all replies received in response to broadcast or recurring messages sent from your account on the previous \[day/week/month]. This report is designed to help users identify actionable replies, allowing them to engage with subscribers effectively and respond to any feedback or inquiries. By analyzing these replies, users can gain valuable insights into subscriber sentiment and the effectiveness of their campaigns. **Frequency**: Daily/Weekly/Monthly **Output**: .csv file **Scope**: Includes data from all lists on the account **Customization**: Users can request to append subscriber-level custom fields to the report, such as CRM IDs (e.g., cons\_id from Blackbaud Luminate Online). These custom fields must be pre-configured within the list in your momoGood Messaging account to appear in the report. **Fields**: * `report_run_date`: The date when the report was generated. * `owner_account_id`: The momoGood Messaging account ID for the owner account of the organization. * `company_name`: The name of the company associated with the momoGood Messaging account. * `list_id`: The unique momoGood Messaging ID of the list from which the messages were sent. * `list_name`: The name of the list in momoGood Messaging. * `recurring_message_id`: The ID of the parent recurring message. Only applicable if the message was a child of a recurring message. * `recurring_message_name`: The Name of the parent recurring message. Only applicable if the message was a child of a recurring message. * `message_id`: The ID of the message in which the subscriber responded to. * `message_name`: The name of the message. Only applicable to broadcast messages, recurring message names will be populated under recurring\_message\_name. * `phone_number`: The phone number of the subscriber who replied. * `record_type`: This represents whether the record is a reply or a reply\_response * `reply_id`: The unique identifier for the reply received from the subscriber. * `reply_response_id`: The unique identifier for the reply response sent by the momoGood Messaging account. * `replied_at`: The time of the reply. (Only if the record\_type is reply) * `responded_at`: The time of the response. (Only if the record\_type is reply\_response) * `reply_content`: The content of the reply. * `response_content`: The content of the reply response. (Only if the record\_type is reply\_response) * `sentiment_score`: A sentiment analysis score assigned to each reply, represented as a decimal value between -1 and 1. Scores near -1 indicate negative sentiment, those near 0 reflect neutral sentiment, and scores approaching 1 indicate positive sentiment. # Broadcast message summary report Source: https://developers.momogood.com/data-hub/reports/broadcast-message-summary-report **Description**: The Messages Summary Report provides a \[daily/weekly/monthly] summary of all broadcast messages sent from your account on the previous day. This report offers insights into message performance, including key metrics related to deliverability and engagement. Users can quickly assess how well their messages reached subscribers and gauge engagement levels, helping to inform future messaging strategies and optimize campaign effectiveness. **Frequency**: Daily/Weekly/Monthly **Output**: .csv file **Scope**: Includes data from all lists on the account **Customization**: No customization is available for this report. **Fields**: * `report_run_date`: The date when the report was generated. * `owner_account_id`: The momoGood Messaging account ID for the owner account of the organization. * `company_name`: The name of the company associated with the momoGood Messaging account. * `list_id`: The unique momoGood Messaging ID of the list from which the messages were sent. * `list_name`: The name of the list in momoGood Messaging. * `sending_at`: The timestamp of when the message started sending. * `sent_at`: The timestamp of when a message finished sending. * `canceled_at`: The timestamp of when a message was cancelled. * `status`: The current status of the message. * `is_timewarp`: Boolean indicating if a message is a timwarp or not. * `message_id`: The ID of the message. * `message_name`: The name of the message sent. * `message_type`: The type of message sent (SMS/MMS). * `recipients`: The number of recipients the message was sent to. * `sms_count`: The number of SMS messages sent. * `mms_count`: The number of MMS messages sent. * `total_parts`: The number of individual parts that were sent. * `messages_delivered`: The number of messages successfully delivered to a subscriber's handset. * `bounces`: The number messages that bounced. * `message_body`: The content of the message body. * `fallback`: The content of the fallback message. Only applicable to MMS messages. * `links`: Links within the message body. * `click_counts`: The number of clicks by subscribers on a link within the message body. * `unique_click_counts`: The number of unique clicks by subscribers on a link within the message body. * `unsubscribed_count`: The number of subscribers who unsubscribed after receiving the message. * `send_cost`: The cost of the message sent. * `segments`: The segments used to define the audience that received the message. # Clicks report Source: https://developers.momogood.com/data-hub/reports/clicks-report **Description**: The Clicks Report provides a comprehensive list of all clicks recorded from the previous \[day/week/month]. This includes clicks from any broadcast or recurring message sent from your account. The report helps users track engagement at the subscriber level, providing valuable insights into campaign performance. **Frequency**: Daily/Weekly/Monthly **Output**: .csv file **Scope**: Includes data from all lists on the account **Customization**: Users can request to append subscriber-level custom fields to the report, such as CRM IDs (e.g., cons\_id from Blackbaud Luminate Online). These custom fields must be pre-configured within the list in your momoGood Messaging account to appear in the report. **Fields**: * `report_run_date`: The date when the report was generated. * `owner_account_id`: The momoGood Messaging account ID for the owner account of the organization. * `company_name`: The name of the company associated with the momoGood Messaging account. * `list_id`: The unique momoGood Messaging ID of the list from which the messages containing the clicks were sent. * `list_name`: The name of the list in momoGood Messaging. * `click_id`: The unique identifier for each click recorded by momoGood Messaging. * `clicked_at`: The exact time when the click occurred. * `subscriber_id`: The ID of the subscriber in momoGood Messaging. * `phone_number`: The phone number of the subscriber who clicked the link. * `message_id`: The ID of the message from which the click originated. * `recurring_message_id`: The ID of the parent recurring message. Only applicable if the message was a child of a recurring message. * `recurring_message_name`: The name of the parent recurring message. Only applicable if the message was a child of a recurring message. * `message_name`: The name of the message. Only applicable to broadcast messages, recurring message names will be populated under recurring\_message\_name. # Donations report Source: https://developers.momogood.com/data-hub/reports/donations-report **Description**: The Donations Report provides a comprehensive list of all donations received and attributed to momoGood Messaging messages from the previous \[day/week/month]. This report enables users to assess the direct impact of their messaging campaigns on fundraising efforts, offering insights into which messages prompted donations. By tracking donation performance, customers can better understand campaign effectiveness and refine their messaging strategies to drive further contributions. **Frequency**: Daily/Weekly/Monthly **Output**: .csv file **Scope**: Includes data from all lists on the account **Customization**: Users can request to append subscriber-level custom fields to the report, such as CRM IDs (e.g., cons\_id from Blackbaud Luminate Online). These custom fields must be pre-configured within the list in your momoGood Messaging account to appear in the report. **Fields**: * `report_run_date`: The date when the report was generated. * `owner_account_id`: The momoGood Messaging account ID for the owner account of the organization. * `company_name`: The name of the company associated with the momoGood Messaging account. * `list_id`: The unique momoGood Messaging ID of the list from which the messages were sent. * `list_name`: The name of the list in momoGood Messaging. * `donation_platform_uid`: The unique identifier from the fundraising platform the donation originated from. * `donated_at`: The timestamp of when the donation occurred. * `message_id`: The ID of the message from which the donation originated. * `amount`: The amount of the donation. * `phone_number`: The phone number of the subscriber who donated as a result of receiving the message. * `created_at`: The timestamp of when the donation was created in momoGood Messaging. # Opts report Source: https://developers.momogood.com/data-hub/reports/opts-report **Description**: The Opts Report provides a comprehensive log of all opt-in and opt-out activities that occurred the previous \[day/week/month]. This report gives users valuable insights into list growth, churn, and overall list health. By tracking subscriber engagement and list changes, users can better understand their audience dynamics and make informed decisions to improve subscriber retention and acquisition. **Frequency**: Daily/Weekly/Monthly **Output**: .csv file **Scope**: Includes data from all lists on the account **Customization**: Users can request to append subscriber-level custom fields to the report, such as CRM IDs (e.g., cons\_id from Blackbaud Luminate Online). These custom fields must be pre-configured within the list in your momoGood Messaging account to appear in the report. **Fields**: * `report_run_date`: The date when the report was generated. * `owner_account_id`: The momoGood Messaging account ID for the owner account of the organization. * `company_name`: The name of the company associated with the momoGood Messaging account. * `list_id`: The unique momoGood Messaging ID of the list from which the messages were sent. * `list_name`: The name of the list in momoGood Messaging. * `phone_number`: The phone number of the subscriber who initiated the opt action. * `opt_id`: The unique identifier for each opt record. * `opt_type`: The type of opt action (in or out). * `opt_in_method`: The method in which the opt action was initiated. (Only for opt-ins) * `api_source`: The api source that triggered the opt action. This only applies to opt records with an opt\_in\_method of api. * `keyword_name`: The keyword associated with an opt-in action. * `opt_out_method`: The method that initiated the opt-out action. * `opt_created_date`: The date the opt record was created. # Recipients report Source: https://developers.momogood.com/data-hub/reports/recipients-report **Description**: The Recipients Report provides a detailed record of all messages sent to individual subscribers from the previous day. This includes broadcast, recurring, autoresponder, system, test, and transactional messages. This report enables users to track each message campaign at the individual subscriber level, offering valuable insights into message deliverability, including whether a message was successfully delivered or bounced. Note: list\_id and list\_name can be null for system messages at the account level. In this case any custom fields tied to a given subscriber will not be returned. **Frequency**: Daily/Weekly/Monthly **Output**: .csv file **Scope**: Includes data from all lists on the account **Customization**: Users can request to append subscriber-level custom fields to the report, such as CRM IDs (e.g., cons\_id from Blackbaud Luminate Online). These custom fields must be pre-configured within the list in your momoGood Messaging account to appear in the report. **Fields**: * `report_run_date`: The date when the report was generated. * `owner_account_id`: The momoGood Messaging account ID for the owner account of the organization. * `company_name`: The name of the company associated with the momoGood Messaging account. * `list_id`: The unique momoGood Messaging ID of the list from which the messages were sent. * `list_name`: The name of the list in momoGood Messaging. * `phone_number`: The phone number of the subscriber that received the message. * `recurring_message_id`: The ID of the parent recurring message. Only applicable if the message was a child of a recurring message. * `message_id`: The unique id of the message the subscriber received. * `momt_id`: The unique id of the individual message sent to the phone number. * `message_name`: The name of the broadcast or recurring message the subscriber received. * `message_type`: This identifies the type of message that was sent. * `broadcast`: Broadcast messages are large audience blast messages sent from within the momoGood Messaging UI. * `recurring`: Recurring messages are scheduled messages set to trigger based off of subscriber actions. * `system`: System messages are default system messages that are triggered based off of subscriber actions (opt-ins, opt-outs) or by texting in keywords like HELP. * `test`: Test messages are messages sent during the broadcast creation process by users to validate the content of the broadcast message they are creating. * `transactional`: Transactional messages are messages sent using our Transactional Message API. * `content`: The content of the message sent to the subscriber. * `sent_at`: The time the message was sent. * `delivery_status`: The status of the message sent to the subscriber. * `Delivered`: The carrier has confirmed the message was received by the subscriber's handset. * `Bounced`: The carrier attempted delivery but was unsuccessful. * `Pending`: Awaiting a response from the carrier. * `bounce_type`: The bounce type of the individual message sent to the subscriber. Only applicable if the delivery\_status is Bounced. * `soft`: The handset is temporarily unable to receive the message (e.g., subscriber's phone is off or out of service). * `hard`: The device is permanently unable to receive messages (e.g., landline, incompatible device, subscriber changed carriers, blocked number, etc). * `total_message_parts`: The number of individual SMS parts sent to the specific subscriber. # Subscriber activity report Source: https://developers.momogood.com/data-hub/reports/subscriber-activity-report **Description**: The Subscriber Activity Report provides a view of your list health for the given period \[day/week/month]. It includes the number of subscribers who have recently joined, unsubscribed, and cleaned. Providing you with insights into how your list is growing over time. **Frequency**: Daily/Weekly/Monthly **Output**: .csv file **Scope**: Includes data from all lists on the account **Customization**: No customization is available for this report. **Fields**: * `report_run_date`: The date when the report was generated. * `owner_account_id`: The momoGood Messaging account ID for the owner account of the organization. * `company_name`: The name of the company associated with the momoGood Messaging account. * `list_id`: The unique momoGood Messaging ID of the list from which the messages were sent. * `list_name`: The name of the list in momoGood Messaging. * `period_starting`: The date/time of the period starting for the report. * `period_ending`: The date/time of the period starting for the report. * `starting_list_size`: The number of active subscribers on the list at the start of the period. * `ending_list_size`: The number of active subscribers on the list at the start of the period. * `change`: The difference between starting\_list\_size and ending\_list\_size. * `subscribers_added`: The number of new subscribers added during the period. * `opt_outs`: The number of unsubscribes that occurred during the period. * `cleans`: The number of cleans that occurred during the period. # Subscribers snapshot report Source: https://developers.momogood.com/data-hub/reports/subscribers-snapshot-report **Description**: The Subscribers Snapshot Report provides a complete, point-in-time snapshot of all subscribers and their attributes. This report allows users to capture the current state of their subscriber list, including key details such as subscription status, custom fields, and engagement data points. It's particularly useful for monitoring list health, performing historical comparisons, and tracking changes in subscriber attributes over time. **Frequency**: Daily/Weekly/Monthly **Output**: .csv file **Scope**: Includes data from all lists on the account **Customization**: No customization is available for this report. **Fields**: * `report_run_date`: The date when the report was generated. * `owner_account_id`: The momoGood Messaging account ID for the owner account of the organization. * `company_name`: The name of the company associated with the momoGood Messaging account. * `list_id`: The unique momoGood Messaging ID of the list from which the messages were sent. * `list_name`: The name of the list in momoGood Messaging. * `subscriber_id`: The unique identifier for each subscriber. * `phone_number`: The phone number of the subscriber. * `carrier`: The carrier for the subscriber's phone number. * `tags`: Any tags associated with the subscriber. * `status`: The current subscription status of the subscriber. * `subscribed_at`: The timestamp when the subscriber first joined the list. * `unsubscribed_at`: The timestamp when the subscriber unsubscribed from the list. * `cleaned_at`: The timestamp of when the subscriber was cleaned from the list. * `opt_in_method`: The method by which the subscriber joined the list. * `most_recent_opt_in`: The timestamp of the subscriber's most recent opt-in action. * `api_source`: The API source of the most recent opt-in. * `brand_affinity_score`: A dynamic AI-generated score that reflects a subscriber's engagement based on reply sentiment, clicks, donations, and opt-out behavior. * `power_segment_label`: A categorical label that places a subscriber into one of five AI-defined engagement segments: VIP Donor, Highly Engaged, Passive Supporter, At-Risk, or Critical Risk, based on their brand affinity score. * `phone_os`: The operating system of the subscriber's phone (e.g., iOS, Android). This data is only available for subscribers who have clicked a link in a message, as it's collected through link tracking. * `custom_fields`: Any custom fields configured in your momoGood Messaging list will be included as separate columns by default. The headers will reflect the merge tag defined when the custom fields were created. # Updated subscribers report Source: https://developers.momogood.com/data-hub/reports/updated-subscribers-report **Description**: The Updated Subscribers Report provides a detailed record of all subscribers whose information was updated during the previous \[day/week/month]. This report offers valuable insights into changes in subscriber data, helping users monitor list health and track updates in subscription status. Subscribers may be included in the report due to changes in their subscription status (e.g., opt-in or opt-out) or updates to custom field attributes, such as name, email, last gift date or any other attributes configured as a custom field on your momoGood Messaging list. **Frequency**: Daily **Output**: .csv file **Scope**: Includes data from all lists on the account **Customization**: No customization is available for this report. **Fields**: * `report_run_date`: The date when the report was generated. * `owner_account_id`: The momoGood Messaging account ID for the owner account of the organization. * `company_name`: The name of the company associated with the momoGood Messaging account. * `list_id`: The unique momoGood Messaging ID of the list from which the messages were sent. * `list_name`: The name of the list in momoGood Messaging. * `subscriber_id`: The unique identifier for each subscriber. * `phone_number`: The phone number of the subscriber. * `carrier`: The carrier for the subscriber's phone number. * `tags`: Any tags associated with the subscriber. * `status`: The current subscription status of the subscriber. * `subscribed_at`: The timestamp when the subscriber first joined the list. * `unsubscribed_at`: The timestamp when the subscriber unsubscribed from the list. * `cleaned_at`: The timestamp of when the subscriber was cleaned from the list. * `opt_in_method`: The method by which the subscriber joined the list. * `most_recent_opt_in`: The timestamp of the subscriber's most recent opt-in action. * `api_source`: The API source of the most recent opt-in. * `brand_affinity_score`: A dynamic AI-generated score that reflects a subscriber's engagement based on reply sentiment, clicks, donations, and opt-out behavior. * `power_segment_label`: A categorical label that places a subscriber into one of five AI-defined engagement segments: VIP Donor, Highly Engaged, Passive Supporter, At-Risk, or Critical Risk, based on their brand affinity score. * `phone_os`: The operating system of the subscriber's phone (e.g., iOS, Android). This data is only available for subscribers who have clicked a link in a message, as it's collected through link tracking. * `custom_fields`: Any custom fields configured in your momoGood Messaging list will be included as separate columns. The headers will reflect the merge tag defined when the custom fields were created. # Authentication Source: https://developers.momogood.com/events-auctions/authentication Session-cookie login flow, optional OTP, and per-namespace authorization rules. All endpoints require an authenticated EMS user session. The session is established via the EMS login flow on the same regional hostname (see [Base URL and regions](/events-auctions/base-url-and-regions)) and is represented as an HTTP cookie. Every subsequent request must echo that cookie back. **Coming Soon — OAuth 2.0 and API-key authentication.** Today the API uses the session-cookie flow described below. Contact [support@givergy.com](mailto:support@givergy.com) to be notified when OAuth or API-key auth becomes available. ## Step 1 — Log in ```http theme={null} POST {EMS_BASE_URL}/checkin/v1/auth/login Content-Type: application/json { "username": "", "password": "", "version": 0 } ``` A successful response sets a session access cookie and, in most deployments, an `X-CSRF-Token` response header. Send the cookie on every subsequent request. If your integration submits non-`GET` requests (none of the endpoints documented here do), also echo the CSRF token back as `X-CSRF-Token`. ## Optional — OTP / multi-factor If your account requires OTP for sign-in, exchange these requests before calling the data endpoints: ```http theme={null} POST {EMS_BASE_URL}/checkin/v1/auth/otp-login/requestCode POST {EMS_BASE_URL}/checkin/v1/auth/otp-login/checkCode ``` `requestCode` triggers OTP delivery (SMS or email per the user's MFA settings). `checkCode` verifies the supplied code and upgrades the session to fully authenticated. ## Step 2 — Authorization rules per family All endpoints share session authentication but apply **different authorization checks** per family: | Family | Path prefix | Authorization | | ------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Custom Data Export | `//v1` | The authenticated user **must be the dedicated service user** provisioned for your integration. Any other authenticated user receives `403 Forbidden`. The user must also have access to the requested event. | | Salesforce | `/salesforce/v1` | The authenticated user must have access to the requested event. No dedicated-user restriction. | | Blackbaud | `/blackbaud/v1` | The authenticated user must have access to the requested event. No dedicated-user restriction. | Custom Data Export endpoints require a dedicated service user provisioned per customer. If you receive `403 Forbidden` with a body like `{"code":"forbidden","message":"Access forbidden: not a client","extra":""}`, the account you authenticated as is not the configured service user for your integration. Contact [support@givergy.com](mailto:support@givergy.com) to provision the right service user. ## Credential handling Session-cookie authentication ties the integration to a specific service-user account and password. Treat the credentials as you would any other privileged secret: * Store them in a secret manager, not in source control or environment files committed to a repo. * Rotate on a schedule and after any suspected compromise. * Avoid sharing credentials across environments (sandbox vs. production). ## Errors specific to authentication | Status | Code | When you'll see it | | ------------------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `401 Unauthorized` | `unauthorized` | Missing or invalid session cookie. Re-run the login flow. | | `403 Forbidden` | `forbidden` | Authenticated but not authorized. For Custom Data Export paths this is usually the dedicated-user check failing. For all paths it can also mean the user does not have access to the requested event. | See the full [Errors page](/events-auctions/errors) for the complete error shape and other status codes. # Base URL and regions Source: https://developers.momogood.com/events-auctions/base-url-and-regions The five regional production hostnames available today and how to determine which region hosts your account. Givergy operates regional production deployments. **Every customer account is hosted in exactly one region**, and every endpoint documented here is served by that region's hostname. Throughout these docs the placeholder `{EMS_BASE_URL}` stands for the production hostname for your account's region. ## Available regions today | Region | Production hostname | Demo / sandbox hostname | | -------------- | ------------------------- | ------------------------------ | | United Kingdom | `https://uk.givergy.com` | `https://uk.demo.givergy.com` | | United States | `https://us.givergy.com` | `https://us.demo.givergy.com` | | Canada | `https://can.givergy.com` | `https://can.demo.givergy.com` | | Australia | `https://aus.givergy.com` | `https://aus.demo.givergy.com` | | Hong Kong | `https://hk.givergy.com` | `https://hk.demo.givergy.com` | Note the **`aus`** prefix for Australia and the **`can`** prefix for Canada — both are intentionally three letters, not the two-letter ISO codes. **Coming Soon — additional regions.** If your data-residency requirements need a region not listed above, contact [support@givergy.com](mailto:support@givergy.com) to discuss timelines. ## Which region am I in? If you don't know which region hosts your account, the simplest way to find out is to ask Givergy: [support@givergy.com](mailto:support@givergy.com). Alternatively, the Givergy product UI for your account loads from one of these subdomains. The part before `.givergy.com` (e.g. `us` in `us.givergy.com`) is your region prefix and resolves to the same hostname as the API base URL. Internally Givergy resolves region from your account locale: | Account locale | Region | | -------------- | ----------------- | | `en_US` | `us.givergy.com` | | `en_CA` | `can.givergy.com` | | `en_AU` | `aus.givergy.com` | | `en_HK` | `hk.givergy.com` | | anything else | `uk.givergy.com` | ## White-label hostnames Some customers operate white-label hostnames (for specific charities or events) that share infrastructure with these regions. **Those are not part of the public API surface and should not be hit directly** — always call the regional hostname for your account. ## Cross-region behavior The five production hostnames are **independent deployments with independent databases**. Cross-region queries are not possible — an integration is always scoped to a single region. If you need data from multiple regions, you'll need separate integrations per region. # Conventions Source: https://developers.momogood.com/events-auctions/conventions Money fields, timestamps, pagination, enum casing, and other conventions shared across all 9 endpoints. The same conventions apply across every endpoint regardless of family (Custom Data Export, Salesforce, or Blackbaud). ## Money fields All amounts are **integers in the event's minor currency unit**: * Pence for GBP (`£1.50` → `150`) * Cents for USD, CAD, AUD, HKD (`$1.50` → `150`) The event's currency is reported on the `Event` record's `currency` field as an ISO 4217 code. ## Timestamps `created` and `updated` fields are **Unix epoch seconds in UTC** — not milliseconds. ```json theme={null} { "created": 1709123456, "updated": 1714003200 } ``` For human-readable times, format these as UTC and convert to the event's timezone (`Event.timezone`, an IANA timezone id) if displaying to end users. ## IDs UUIDs unless otherwise specified. ## The `since` parameter | Parameter | Type | Default | Notes | | --------- | -------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------ | | `since` | long (epoch seconds) | `1606062358` (2020-11-12) | The server filters records by `updated >= since`. Use `-1` (or any past epoch) to backfill everything. | The default is a past epoch — leaving it off returns all records updated since that date, which for most accounts is effectively "everything." Pass an explicit `since` value to scope the response to recently-updated records. See the [polling pattern](/events-auctions/polling-pattern) for the recommended way to use `since` for incremental sync. ## The `q` parameter A simple full-text search. Empty string disables search. For bundle endpoints (`/items`, `/purchases`), the same `q` filters each category (buy-nows, auction items, etc.) **independently**. ## Pagination | Parameter | Type | Default | Notes | | --------- | ---- | ------- | -------------------------- | | `offset` | int | `0` | Records to skip. | | `limit` | int | `1000` | Page size. Maximum `1000`. | For bundle endpoints (`/items`, `/purchases`), `offset` and `limit` apply **per category** in the response, not across the whole bundle. The bundle's wrapper structure (its keys) is constant; only the array contents grow or shrink. ## Status filter All list endpoints implicitly filter to records with `ACTIVE` status. Archived, inactive, pending, and obfuscated records are not returned. ## Enum casing Enum values returned by the API are serialized in **lowercase**: ```json theme={null} { "status": "active", "processorType": "stripe", "paymentStatus": "paid", "giftAidStatus": "yes" } ``` Older Givergy reference material may show uppercase enum values (e.g. `ACTIVE`, `STRIPE`). Those are incorrect — the wire format is lowercase. Code-generated clients that assume uppercase will not deserialize correctly. ## Content type and compression | Header | Value | | --------------------------------- | -------------------------------------------------------- | | Response `Content-Type` | `application/json` | | Response compression | gzip when `Accept-Encoding: gzip` is sent on the request | | Response `ETag` / `Cache-Control` | Not emitted | None of these endpoints emit `ETag` or `Cache-Control: max-age`. For incremental sync, use the [polling pattern](/events-auctions/polling-pattern) with `since`, not HTTP caching. # List events Source: https://developers.momogood.com/events-auctions/endpoints/events GET /{your-namespace}/v1/events — list events the service user can access, filtered by `since`. Custom Data Export only today; coming soon on the connector families. ```http theme={null} GET {EMS_BASE_URL}//v1/events ``` Returns events the dedicated service user has access to and that have changed since the `since` cursor. This endpoint is **available on the Custom Data Export family only** today. The Salesforce and Blackbaud connector namespaces don't expose a list-events endpoint — those integrations typically receive event IDs out-of-band from the destination CRM. **Coming Soon — list-events on the connector families.** Contact [support@givergy.com](mailto:support@givergy.com) if you need it. Custom Data Export endpoints require a dedicated service user provisioned per customer. Contact [support@givergy.com](mailto:support@givergy.com) to set up your integration. ## Authorization The authenticated caller must be the dedicated service user provisioned for your Custom Data Export integration. Any other authenticated user receives `403 Forbidden`. See [Authentication → Authorization rules per family](/events-auctions/authentication#step-2-authorization-rules-per-family). ## Query parameters | Name | Type | Default | Notes | | --------- | -------------------- | ------------ | ---------------------------------------------------------- | | `since` | long (epoch seconds) | `1606062358` | Lower bound on `updated`. Use `-1` to backfill everything. | | `orderBy` | string | `createdAsc` | See ordering options below. | | `offset` | int | `0` | Pagination offset. | | `limit` | int | `1000` | Page size. Maximum `1000`. | ### Ordering options `orderBy` accepts any of: `createdAsc`, `createdDesc`, `updatedAsc`, `updatedDesc`, `eventDateAsc`, `eventDateDesc`, `startTimeAsc`, `startTimeDesc`, `endTimeAsc`, `endTimeDesc`, `nameAsc`, `nameDesc`, `clientNameAsc`, `clientNameDesc`, `agentNameAsc`, `agentNameDesc`, `venueNameAsc`, `venueNameDesc` ## Response [`Event[]`](/events-auctions/schemas#event-custom-data-export-variant) — Custom Data Export variant. Includes `projectType` and `externalId` fields not present on the connector variants. ## Example ```bash theme={null} curl --cookie session.cookie \ '{EMS_BASE_URL}//v1/events?since=1714000000&orderBy=updatedDesc&limit=100' ``` ```json theme={null} [ { "id": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "name": "Spring Charity Gala 2026", "status": "active", "inAidOf": "Hope Foundation", "startTime": 1715250600, "endTime": 1715279400, "eventDate": 1715250600, "timezone": "Europe/London", "currency": "GBP", "created": 1709123456, "updated": 1714003200, "projectType": "auction", "externalId": "EXT-2026-SPRING-001" } ] ``` ## What's in the response See the full [`Event` schema](/events-auctions/schemas#event-custom-data-export-variant) for the field-by-field reference. Key things to know: * All amounts are integers in the event's minor currency unit (see [Conventions → Money fields](/events-auctions/conventions#money-fields)). * Timestamps are Unix epoch seconds in UTC. * `status` is always `"active"` because of the implicit active-only filter on list endpoints. * `timezone` is an IANA timezone id (e.g. `Europe/London`, `America/New_York`). ## Next steps Once you have an event id, fetch its detail: * [List items for the event](/events-auctions/endpoints/items) * [List purchases for the event](/events-auctions/endpoints/purchases) * [List guests for the event](/events-auctions/endpoints/guests) For ongoing sync, see the [polling pattern](/events-auctions/polling-pattern). # List guests for an event Source: https://developers.momogood.com/events-auctions/endpoints/guests Guests registered for the event with consent metadata. Custom Data Export, Salesforce, and Blackbaud variants. Lists guests registered for an event, joined with their consent record. Available across all three families: | Family | Path | Payload | | ------------------ | -------------------------------------------------- | ------------------------------------------------------------------ | | Custom Data Export | `GET //v1/events/{eventId}/guests` | Full record including `externalId`, `smsOptIn`, and `companyName`. | | Salesforce | `GET /salesforce/v1/events/{eventId}/guests` | Lean record. Omits `externalId`, `smsOptIn`, and `companyName`. | | Blackbaud | `GET /blackbaud/v1/events/{eventId}/guests` | Same as Salesforce variant. | ## Authorization The authenticated caller must be the dedicated service user provisioned for your integration, and have access to the event. Custom Data Export endpoints require a dedicated service user provisioned per customer. Contact [support@givergy.com](mailto:support@givergy.com) to set up your integration. The authenticated caller must have access to the event. No dedicated-user restriction. The Salesforce connector is a partner-specific integration. Contact [support@givergy.com](mailto:support@givergy.com) to enable the connector for your organization. The authenticated caller must have access to the event. No dedicated-user restriction. The Blackbaud connector is a partner-specific integration. Contact [support@givergy.com](mailto:support@givergy.com) to enable the connector for your organization. ## Path parameters | Name | Type | Notes | | --------- | ---- | ---------------------------------------------------------------------------- | | `eventId` | UUID | EMS event id (returned by [List events](/events-auctions/endpoints/events)). | ## Query parameters | Name | Type | Default | Notes | | -------- | ------ | ------------ | ----------------------------------------- | | `q` | string | `""` | Full-text search across name, email, etc. | | `since` | long | `1606062358` | `updated >= since`. | | `offset` | int | `0` | Pagination offset. | | `limit` | int | `1000` | Page size. Maximum `1000`. | ## Response [`Guest[]`](/events-auctions/schemas#guest-custom-data-export-variant) — Custom Data Export variant. Includes `externalId`, `smsOptIn`, and `companyName` fields not present on the connector variants. [`SalesforceGuest[]`](/events-auctions/schemas#guest-connector-variants-salesforce-and-blackbaud) — a lean variant of `Guest`. Compared to the Custom Data Export payload, the Salesforce guest object **omits** `externalId`, `smsOptIn`, and `companyName`. Use the Custom Data Export endpoint if you need any of those three fields. [`BlackbaudGuest[]`](/events-auctions/schemas#guest-connector-variants-salesforce-and-blackbaud) — same shape as `SalesforceGuest`. Omits `externalId`, `smsOptIn`, and `companyName`. Use the Custom Data Export endpoint if you need any of those three fields. ## Example ```bash theme={null} curl --cookie session.cookie \ '{EMS_BASE_URL}//v1/events/8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10/guests?since=1714000000&limit=500' ``` ```json theme={null} [ { "id": "f0000001-0000-4000-8000-000000000001", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "firstName": "Alice", "lastName": "Smith", "email": "alice.smith@example.com", "mobile": "+44 7700 900123", "mainAddress": { "name": "Home", "line1": "12 High Street", "line2": null, "line3": null, "line4": null, "town": "London", "postcode": "SW1A 1AA", "state": null, "country": "GB", "recipient_name": "Alice Smith" }, "giftAidAddress": null, "taxReceiptAidAddress": null, "created": 1709200000, "updated": 1714000000, "consentAsked": true, "consentStatus": "active", "consentChannels": "email,sms", "externalId": "EXT-G-001", "smsOptIn": true, "companyName": null } ] ``` ```bash theme={null} curl --cookie session.cookie \ '{EMS_BASE_URL}/salesforce/v1/events/8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10/guests?since=1714000000' ``` ```json theme={null} [ { "id": "f0000001-0000-4000-8000-000000000001", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "firstName": "Alice", "lastName": "Smith", "email": "alice.smith@example.com", "mobile": "+44 7700 900123", "mainAddress": { "...": "see AddressDetail schema" }, "giftAidAddress": null, "taxReceiptAidAddress": null, "created": 1709200000, "updated": 1714000000, "consentAsked": true, "consentStatus": "active", "consentChannels": "email,sms" } ] ``` ```bash theme={null} curl --cookie session.cookie \ '{EMS_BASE_URL}/blackbaud/v1/events/8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10/guests?since=1714000000' ``` Same response shape as the Salesforce variant — omits `externalId`, `smsOptIn`, and `companyName`. ## Consent fields Every guest record carries three consent fields: | Field | Type | Description | | ----------------- | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | `consentAsked` | boolean | Whether the guest has been prompted for consent. | | `consentStatus` | [`Status` enum](/events-auctions/schemas#status-enum) | Typically `"active"` or `"inactive"` for consent records. | | `consentChannels` | string | Comma-separated channels the guest has opted in to (e.g. `email,sms,post`). Empty string when none. | The consent record is owned by the event (`CLIENT` consent owner), not a multi-tenant consent platform — opt-in choices apply to communication from the event organizer. ## Address fields Each guest may have up to three [`AddressDetail`](/events-auctions/schemas#addressdetail) records: | Field | Purpose | | ---------------------- | -------------------------------- | | `mainAddress` | Primary postal address. | | `giftAidAddress` | UK Gift Aid declaration address. | | `taxReceiptAidAddress` | US tax-receipt address. | All three may be null. See [`AddressDetail`](/events-auctions/schemas#addressdetail) for the field-by-field reference (note the snake\_case `recipient_name` field). # List items for an event Source: https://developers.momogood.com/events-auctions/endpoints/items Buy-now items, auction lots, pledges, raffles, GLI raffles, and tickets grouped by category. Custom Data Export and Blackbaud variants today. Lists all sellable / biddable items for an event, grouped by category, as an [`ItemsBundle`](/events-auctions/schemas#itemsbundle). Available in two of the three families today: | Family | Path | Payload | | ------------------ | ------------------------------------------------- | ---------------------------------------------------- | | Custom Data Export | `GET //v1/events/{eventId}/items` | Full record fields. | | Blackbaud | `GET /blackbaud/v1/events/{eventId}/items` | Lean record fields tailored for Blackbaud ingestion. | **Coming Soon — list-items on the Salesforce connector family.** If you need item data via a Salesforce-shaped payload, contact [support@givergy.com](mailto:support@givergy.com). ## Authorization The authenticated caller must be the dedicated service user provisioned for your integration, and have access to the event. Custom Data Export endpoints require a dedicated service user provisioned per customer. Contact [support@givergy.com](mailto:support@givergy.com) to set up your integration. The authenticated caller must have access to the event. No dedicated-user restriction. The Blackbaud connector is a partner-specific integration. Contact [support@givergy.com](mailto:support@givergy.com) to enable the connector for your organization. ## Path parameters | Name | Type | Notes | | --------- | ---- | ---------------------------------------------------------------------------- | | `eventId` | UUID | EMS event id (returned by [List events](/events-auctions/endpoints/events)). | ## Query parameters | Name | Type | Default | Notes | | -------- | ------ | ------------ | ------------------------------------------ | | `q` | string | `""` | Full-text filter applied **per category**. | | `since` | long | `1606062358` | `updated >= since`. | | `offset` | int | `0` | Applied **per category** independently. | | `limit` | int | `1000` | Page size per category. Maximum `1000`. | `offset` and `limit` apply **per category** in the response, not across the whole bundle. If you have more than 1000 records in any single category, paginate by re-issuing the request with rising `offset` until every category returns an empty array. See [Polling pattern → Bundle pagination caveat](/events-auctions/polling-pattern#bundle-pagination-caveat). ## Response [`ItemsBundle`](/events-auctions/schemas#itemsbundle) — always the same wrapper shape, with the per-record fields varying by family: Returns the **full variants** of `BuyNowItem`, `AuctionItem`, `Pledge`, `Raffle`, `Ticket`, and `GliRaffle`. The Custom Data Export item types include descriptive fields the connector variants strip: * `revenueStreamType`, `externalId`, `categories`, `irsSubcategory` * `startPrice`, `increments`, `description`, `termsDescription` * `taxRate`, `estimate` (where applicable) See [Payload customization examples](/events-auctions/overview#payload-customization-examples) for the full comparison. Returns the **Blackbaud (lean) variants** of every item type. Compared to Custom Data Export, descriptive fields are stripped — the connector returns only what Blackbaud's data model natively ingests. See [Payload customization examples](/events-auctions/overview#payload-customization-examples) for the per-type field list. ## Example ```bash theme={null} curl --cookie session.cookie \ '{EMS_BASE_URL}//v1/events/8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10/items?since=1714000000' ``` See the [full `ItemsBundle` (Custom Data Export) example response](/events-auctions/schemas#example-itemsbundle-custom-data-export-response). ```bash theme={null} curl --cookie session.cookie \ '{EMS_BASE_URL}/blackbaud/v1/events/8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10/items?since=1714000000' ``` Same wrapper shape as the Custom Data Export example, but each record has the connector-stripped field set. ## What's in the response `ItemsBundle` has six top-level keys, each holding an array of records of one type: | Wrapper key | Record type | What it represents | | -------------- | ----------------------------------------------------- | ----------------------------------------------------- | | `buyNows` | [`BuyNowItem`](/events-auctions/schemas#buynowitem) | Fixed-price items guests can purchase immediately. | | `auctionItems` | [`AuctionItem`](/events-auctions/schemas#auctionitem) | Auction lots that guests bid on. | | `pledges` | [`Pledge`](/events-auctions/schemas#pledge) | Donation asks (fixed or open-amount). | | `prizeDraws` | [`Raffle`](/events-auctions/schemas#raffle) | Standard ticketed prize draws. | | `gliRaffles` | [`GliRaffle`](/events-auctions/schemas#gliraffle) | GLI-regulated raffles (separate compliance handling). | | `tickets` | [`Ticket`](/events-auctions/schemas#ticket) | Event-entry ticket types. | The wrapper shape is constant across every family — only the contents of each array change between the Custom Data Export and connector variants. # List purchases for an event Source: https://developers.momogood.com/events-auctions/endpoints/purchases Committed purchases, donations, and winning auction bids grouped by category. Custom Data Export, Salesforce, and Blackbaud variants. Lists committed purchases, donations, and winning auction bids for an event, grouped by category, as a [`PurchasesBundle`](/events-auctions/schemas#purchasesbundle). Available across all three families: | Family | Path | Payload | | ------------------ | ----------------------------------------------------- | ------------------------------------------------------------- | | Custom Data Export | `GET //v1/events/{eventId}/purchases` | Includes payment status, processor type, and project segment. | | Salesforce | `GET /salesforce/v1/events/{eventId}/purchases` | Payment metadata stripped. Tailored for Salesforce ingestion. | | Blackbaud | `GET /blackbaud/v1/events/{eventId}/purchases` | Payment metadata stripped. Tailored for Blackbaud ingestion. | ## Authorization The authenticated caller must be the dedicated service user provisioned for your integration, and have access to the event. Custom Data Export endpoints require a dedicated service user provisioned per customer. Contact [support@givergy.com](mailto:support@givergy.com) to set up your integration. The authenticated caller must have access to the event. No dedicated-user restriction. The Salesforce connector is a partner-specific integration. Contact [support@givergy.com](mailto:support@givergy.com) to enable the connector for your organization. The authenticated caller must have access to the event. No dedicated-user restriction. The Blackbaud connector is a partner-specific integration. Contact [support@givergy.com](mailto:support@givergy.com) to enable the connector for your organization. ## Path parameters | Name | Type | Notes | | --------- | ---- | ---------------------------------------------------------------------------- | | `eventId` | UUID | EMS event id (returned by [List events](/events-auctions/endpoints/events)). | ## Query parameters | Name | Type | Default | Notes | | -------- | ---- | ------------ | --------------------------------------- | | `since` | long | `1606062358` | `updated >= since`. | | `offset` | int | `0` | Applied **per category** independently. | | `limit` | int | `1000` | Page size per category. Maximum `1000`. | `offset` and `limit` apply **per category** in the response, not across the whole bundle. If you have more than 1000 records in any single category, paginate by re-issuing the request with rising `offset` until every category returns an empty array. See [Polling pattern → Bundle pagination caveat](/events-auctions/polling-pattern#bundle-pagination-caveat). ## Response [`PurchasesBundle`](/events-auctions/schemas#purchasesbundle) — always the same wrapper shape, with the per-record fields varying by family. Returns the **full variants** of every purchase type. Custom Data Export records additionally include: * `projectSegment` — free-form reporting segment * `processorType` — [`ProcessorType`](/events-auctions/schemas#processortype-enum) enum (Stripe, PayPal, cash, etc.) * `paymentStatus` — [`PaymentStatus`](/events-auctions/schemas#paymentstatus-enum) enum (paid, unpaid, part\_paid, etc.) These three fields are **absent** from every purchase record on the Salesforce and Blackbaud variants. Returns the **Salesforce (lean) variants**. Every purchase record **omits** `projectSegment`, `processorType`, and `paymentStatus`. Use the Custom Data Export endpoint if you need payment metadata. Returns the **Blackbaud (lean) variants**. Identical to the Salesforce variant — every purchase record omits `projectSegment`, `processorType`, and `paymentStatus`. Use the Custom Data Export endpoint if you need payment metadata. ## Example ```bash theme={null} curl --cookie session.cookie \ '{EMS_BASE_URL}//v1/events/8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10/purchases?since=1714000000' ``` See the [full `PurchasesBundle` (Custom Data Export) example response](/events-auctions/schemas#example-purchasesbundle-custom-data-export-response). ```bash theme={null} curl --cookie session.cookie \ '{EMS_BASE_URL}/salesforce/v1/events/8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10/purchases?since=1714000000' ``` Same wrapper shape as the Custom Data Export example, but every record has `projectSegment`, `processorType`, and `paymentStatus` removed. ```bash theme={null} curl --cookie session.cookie \ '{EMS_BASE_URL}/blackbaud/v1/events/8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10/purchases?since=1714000000' ``` Same as the Salesforce variant. ## What's in the response `PurchasesBundle` has six top-level keys, each holding an array of records of one type: | Wrapper key | Record type | What it represents | | -------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------- | | `buyNowPurchases` | [`BuyNowPurchase`](/events-auctions/schemas#buynowpurchase) | Completed purchases of buy-now items. | | `winningBids` | [`AuctionBid`](/events-auctions/schemas#auctionbid) | Winning bids on auction lots. (`count` is always 1; no `count` field.) | | `donations` | [`Donation`](/events-auctions/schemas#donation) | Pledged donations, including Gift Aid status. | | `rafflePurchases` | [`RafflePurchase`](/events-auctions/schemas#rafflepurchase) | Raffle ticket purchases, including `winningCount`. | | `gliRafflePurchases` | [`GliRafflePurchase`](/events-auctions/schemas#glirafflepurchase) | GLI-regulated raffle ticket purchases. | | `ticketPurchases` | [`TicketPurchase`](/events-auctions/schemas#ticketpurchase) | Event-entry ticket purchases. | All purchase records share a common base of fields (`id`, `guestId`, `amount`, `created`, `updated`, etc.) plus the type-specific fields listed in the schema. See [`PurchasesBundle`](/events-auctions/schemas#purchasesbundle) for the full breakdown. ## Payment-status handling tips For most reporting use cases on the Custom Data Export variant, treat the following `paymentStatus` values as "money received": * `paid` * `part_paid` * `overpaid` * `split` See the [`PaymentStatus` enum](/events-auctions/schemas#paymentstatus-enum) for the full list. # Errors Source: https://developers.momogood.com/events-auctions/errors JSON error shape and the HTTP status codes returned across every endpoint. ## Error body shape All errors return a JSON body of the form: ```json theme={null} { "code": "", "message": "", "extra": "" } ``` The `extra` field carries the most-useful piece of context for debugging — typically a UUID or field path that explains why the request was rejected. ## Status codes | HTTP | Code | Cause | | ------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `400 Bad Request` | varies | Malformed query parameter (for example, `limit` greater than `1000`, or a non-numeric `since`). | | `401 Unauthorized` | `unauthorized` | Missing or invalid session cookie. Re-authenticate via the [login flow](/events-auctions/authentication). | | `403 Forbidden` | `forbidden` | The caller is not authorized. For Custom Data Export paths this is usually the dedicated service-user check failing. For all paths, it can also mean the user does not have access to the requested event. | | `404 Not Found` | `not_found` | The supplied `eventId` does not resolve to an event the caller can see — either no event with that id exists, or the event is in a region/account the caller cannot access. | | `429 Too Many Requests` | — | Rate-limit zone exceeded. Back off and retry. See [Rate limiting](/events-auctions/rate-limiting). | | `503 Service Temporarily Unavailable` | — | Sustained traffic above rate-limit zone capacity, or an upstream component is overloaded. Retry with exponential backoff. | | `5xx` (other) | varies | Transient server error. Retry with exponential backoff. | ## Example: 403 on a Custom Data Export path ```json theme={null} { "code": "forbidden", "message": "Access forbidden: not a client", "extra": "11111111-2222-3333-4444-555555555555" } ``` This is the response you'll get if you call a Custom Data Export endpoint with a session that isn't the configured service user for your integration. The `extra` field contains your authenticated user's UUID — useful when contacting support. The exact `message` text varies per integration namespace; the `code` and `extra` shape are consistent. If you see this error and believe your account should have access, contact [support@givergy.com](mailto:support@givergy.com) with the UUID from the `extra` field. The team can verify your account's provisioning state. ## Retry guidance | Status | Retry? | How | | ------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `400` | No — fix the request | Inspect `extra`, correct the offending parameter, then resend. | | `401` | After re-auth | Re-run the login flow to get a fresh session cookie. | | `403` | No — escalate | The caller isn't authorized for this resource. Contact [support@givergy.com](mailto:support@givergy.com) if you expected to have access. | | `404` | Sometimes | If the `eventId` is correct, the event may not yet be visible to your user. Check with the event owner. | | `429` / `503` | Yes — with backoff | Exponential backoff starting at a few seconds. See [Rate limiting](/events-auctions/rate-limiting). | | `5xx` | Yes — with backoff | Treat as transient. | # Limitations and caveats Source: https://developers.momogood.com/events-auctions/limitations What this API doesn't do today, what's on the roadmap, and a few edge cases worth knowing before you build. A short list of intentional limits, edge cases, and Coming Soon items worth knowing before you build. ## Read-only None of the endpoints documented here accept writes. Event creation, item creation, payment capture, refunds, and any other state-changing operations are performed through the Givergy product UI. **Coming Soon — write/mutation endpoints.** Write capabilities (creating events, items, processing payments) are scoped per integration. Contact [support@givergy.com](mailto:support@givergy.com) to discuss your use case. ## Connector payloads are leaner than Custom Data Export The Salesforce and Blackbaud connector endpoints intentionally restrict the payload to the subset their respective CRMs natively ingest. If you need: * Payment status, processor type, or project segment fields, or * Descriptive item fields (description, terms, categories, IRS subcategories, bid increments, starting prices, tax rates, estimates), or * Guest `externalId`, `smsOptIn`, or `companyName` … you must use the Custom Data Export family. See [Payload customization examples](/events-auctions/overview#payload-customization-examples) on the Overview page for the full per-record comparison. For a new integration, we'd shape the payload to your destination — adding fields, dropping fields, or transforming values at the boundary. The connector trims aren't fixed; they're examples of what we've delivered before. ## No list-events endpoint on the connector families The Salesforce and Blackbaud families don't expose a `/events` listing endpoint today. Integrations using those families typically receive event IDs out-of-band (from the destination CRM) and call `/items`, `/purchases`, and `/guests` directly. **Coming Soon — list-events on connector families.** Contact [support@givergy.com](mailto:support@givergy.com) if you need it. ## Multi-region: independent deployments The five production hostnames listed in [Base URL and regions](/events-auctions/base-url-and-regions) are **independent deployments with independent databases**. Cross-region queries aren't possible — an integration is always scoped to a single region. If you need data from multiple regions, run separate integrations per region. **Coming Soon — additional regions.** Contact [support@givergy.com](mailto:support@givergy.com) if your data-residency needs aren't covered today. ## Auth model: long-lived service-user credential Session-cookie auth requires a long-lived service-user credential. Plan for rotation and secret storage. See [Authentication](/events-auctions/authentication) for credential-handling guidance. **Coming Soon — OAuth 2.0 and API-key auth** as a replacement for session-cookie. Contact [support@givergy.com](mailto:support@givergy.com) to be notified when available. ## Enum serialization: lowercase only All enum values are lowercase in JSON. Code-generated clients that assume uppercase will not deserialize correctly. See [Conventions](/events-auctions/conventions#enum-casing). ## `giftAidStatus` values Only `not_asked`, `yes`, `no` are valid wire values. Treat anything else as a future addition and surface it as opaque rather than crashing — Givergy may add new values over time without considering that a breaking change. Earlier Givergy reference material listed values like `CLAIMED`, `PENDING`, `NOT_REQUESTED`. Those were incorrect. ## Rate-limit thresholds aren't publicly fixed Concrete rate-limit thresholds are tuned periodically and vary by region. Plan for **1 request per second per integrator** and contact [support@givergy.com](mailto:support@givergy.com) in advance if you expect to need higher quotas. See [Rate limiting](/events-auctions/rate-limiting). ## No webhook notifications today There are no push notifications for resource changes today. Use the [polling pattern](/events-auctions/polling-pattern) with `since`. **Coming Soon — webhook notifications.** Contact [support@givergy.com](mailto:support@givergy.com) to express interest. ## New connector and destination shapes **Coming Soon — new CRM and warehouse connectors.** HubSpot, Microsoft Dynamics, NetSuite, Raiser's Edge, Snowflake, BigQuery, and any other destination with a stable ingestion interface. Each new family is built on the same foundation as the Custom Data Export and existing connector shapes. Contact [support@givergy.com](mailto:support@givergy.com) to scope. # Overview Source: https://developers.momogood.com/events-auctions/overview A read-only HTTP surface for exporting Givergy event data into the systems you already run — CRMs, data warehouses, reporting tools, and custom destinations. The Events & Auctions API gives third-party developers a read-only HTTP surface for exporting Givergy fundraising-event data — events, items, purchases, and guests — into the systems you already operate. Use it to keep your CRM, data warehouse, or internal reporting in sync with what's happening on the Givergy platform. **Coming Soon — your custom integration.** Each endpoint family below was originally built for a specific customer's destination system. The same foundation lets us shape a new integration to your CRM, data warehouse, or internal stack — HubSpot, Microsoft Dynamics, NetSuite, Raiser's Edge, Snowflake, BigQuery, or anything else with a stable ingestion interface. Contact [support@givergy.com](mailto:support@givergy.com) to scope yours. ## How an integration is delivered 1. You tell us the destination system, the fields you need, the sync cadence, and the data-residency region. 2. We provision a service user, assign a namespace under `{EMS_BASE_URL}//v1/...`, and shape the payload to match your destination. 3. You point your sync job at the endpoints documented here. The behaviour — pagination, `since`-based polling, error shapes, enum casing — stays consistent across every integration we deliver. ## Integration families available today We currently ship three integration shapes. Each is a working pattern in production for at least one customer; we extend or fork them for new engagements. The richest, general-purpose export. Returns every available field — payment status, processor type, project segment, descriptive item metadata, and external reference IDs. Path namespace is assigned per integration. **The recommended shape when your destination can ingest the full payload.** `/salesforce/v1/...` — payload shaped for native Salesforce ingestion (intentionally leaner than the Custom Data Export shape). `/blackbaud/v1/...` — payload shaped for native Blackbaud ingestion (same trimmed shape as the Salesforce connector). Every family requires a service user provisioned by Givergy. Contact [support@givergy.com](mailto:support@givergy.com) to set up your integration — whether you're enabling one of the existing shapes for your account or scoping a new one. ## Which family should I use? | If you need… | Use | | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | | Payment status, processor type, or project-segment fields | **Custom Data Export** | | Descriptive item fields (description, terms, categories, IRS subcategories, bid increments, starting prices, tax rates, estimates) | **Custom Data Export** | | Guest external IDs, SMS opt-in flag, or company name | **Custom Data Export** | | Salesforce-shaped payload for native CRM ingestion | **Salesforce connector** | | Blackbaud-shaped payload for native CRM ingestion | **Blackbaud connector** | | Any other destination (HubSpot, Snowflake, internal warehouse, etc.) | Talk to us — we'll scope a new integration shape based on Custom Data Export | ## How the docs are organized * **[Authentication](/events-auctions/authentication)** — session-cookie login flow, optional OTP, per-family authorization rules. * **[Base URL and regions](/events-auctions/base-url-and-regions)** — the five regional hostnames in production today. * **[Conventions](/events-auctions/conventions)** — money fields, timestamps, pagination, enum casing, content type. * **[Rate limiting](/events-auctions/rate-limiting)** — plan for 1 request per second per integrator. * **[Errors](/events-auctions/errors)** — JSON error shape and the status codes you'll see. * **[Polling pattern](/events-auctions/polling-pattern)** — recommended sync flow using the `since` cursor. * **[Limitations](/events-auctions/limitations)** — what the API doesn't do today, and what's on the roadmap. * **Endpoints** — one page per resource (Events / Items / Purchases / Guests), with each family's variant shown side-by-side. * **[Schemas](/events-auctions/schemas)** — `Event`, `ItemsBundle`, `PurchasesBundle`, `Guest`, `AddressDetail`, and the enums. ## Payload customization examples The three families differ in **which fields each record carries**. Every family returns the same JSON wrapper shapes (`ItemsBundle` and `PurchasesBundle` have identical keys); the per-record fields are shaped to the destination. The table below shows what the Custom Data Export shape adds on top of the connector shapes — useful as a concrete example of the kind of customization we deliver per integration. | Record type | Fields on Custom Data Export only (omitted from Salesforce / Blackbaud) | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Event` | `projectType`, `externalId` | | `Guest` | `externalId`, `smsOptIn`, `companyName` | | `BuyNowItem` | `revenueStreamType`, `externalId`, `categories`, `irsSubcategory`, `startPrice`, `increments`, `description`, `termsDescription`, `taxRate`, `estimate` | | `AuctionItem` | `revenueStreamType`, `externalId`, `categories`, `irsSubcategory`, `startPrice`, `increments`, `type`, `description`, `termsDescription`, `estimate` | | `Pledge` | (identical — no difference) | | `Raffle` | `revenueStreamType` | | `GliRaffle` | `revenueStreamType`, `externalId` | | `Ticket` | `revenueStreamType`, `externalId` | | `BuyNowPurchase` | `projectSegment`, `processorType`, `paymentStatus` | | `AuctionBid` | `projectSegment`, `processorType`, `paymentStatus` | | `RafflePurchase` | `projectSegment`, `processorType`, `paymentStatus` | | `GliRafflePurchase` | `projectSegment`, `processorType`, `paymentStatus` | | `TicketPurchase` | `projectSegment`, `processorType`, `paymentStatus` | | `Donation` | `projectSegment`, `processorType`, `paymentStatus` | For a new integration, we'd discuss the destination's schema and shape the payload to match — adding fields not shown here, dropping fields you don't need, or transforming values at the boundary. ## What's on the roadmap **Coming Soon — new CRM and warehouse connectors.** New families on the same foundation as Salesforce and Blackbaud. If you have a destination in mind, [contact us](mailto:support@givergy.com) and we'll add it to the roadmap. **Coming Soon — write/mutation endpoints.** The current API is read-only. Write capabilities (creating events, items, processing payments) are scoped per integration. Contact us to discuss your use case. **Coming Soon — webhook notifications.** Push notifications for resource changes. Until then, use the [polling pattern](/events-auctions/polling-pattern) with `since`. **Coming Soon — OAuth 2.0 and API-key authentication.** The current API uses session-cookie auth. Modern auth options are on the roadmap. **Coming Soon — bulk and async export jobs.** For one-time large backfills, ask us about async export — useful when polling individual events at scale isn't the right shape. ## Glossary A few terms used throughout the docs: | Term | Meaning | | ----------------------- | ---------------------------------------------------------------------------------------------------------------- | | **Event** (gala) | A fundraising event hosted on Givergy. The top-level container for items, purchases, and guests. | | **Lot** | An auction item that guests bid on. | | **Buy-now** | A fixed-price item guests can purchase immediately (no bidding). | | **Pledge** | A donation ask. Can be fixed-amount or open-amount. | | **Raffle** | A ticketed prize draw. | | **GLI raffle** | A raffle regulated by Gaming Laboratories International. Compliance is handled separately from standard raffles. | | **Ticket** | An event-entry ticket type (not a raffle ticket). | | **Committed purchase** | A finalized transaction — distinct from active bids or pending payments. | | **Winning bid** | The top bid on an auction item once the auction closes. | | **Processor type** | The payment method used (Stripe, PayPal, cash, cheque, etc.). | | **Revenue stream type** | An internal accounting category for items. | | **Project segment** | A free-form reporting tag for grouping purchases. | | **IRS subcategory** | A US-tax reporting classification for items. | | **Gift Aid** | A UK-only HMRC mechanism letting charities reclaim tax on donations. | | **Namespace** | The path prefix assigned to your integration (e.g. `/salesforce/v1`, `/blackbaud/v1`, or a custom prefix). | # Polling pattern Source: https://developers.momogood.com/events-auctions/polling-pattern Recommended incremental-sync flow using the `since` cursor. Webhooks coming soon. **Coming Soon — webhook notifications.** Push notifications for resource changes. Until then, use the polling pattern below. Contact [support@givergy.com](mailto:support@givergy.com) to express interest. **Coming Soon — bulk and async export jobs.** For one-time large backfills, ask us about async export — useful when polling individual events at scale isn't the right shape. ## The recommended sync flow The simplest reliable approach is `since`-based polling. The examples below assume the Custom Data Export family; substitute the path prefix for `/salesforce/v1` or `/blackbaud/v1` as appropriate. 1. **On first run**, call `GET //v1/events?since=-1` to backfill all events visible to your service user. 2. **For each event id returned** (paginate with `offset` / `limit` if you have more than 1000 events): * `GET //v1/events/{eventId}/items?since=` * `GET //v1/events/{eventId}/purchases?since=` * `GET //v1/events/{eventId}/guests?since=` 3. **Persist `max(updated)` across all records returned** as the next `lastSyncTs`. Keep fine-grained cursors per resource if you need different sync cadences. 4. **On subsequent runs**, repeat with the saved cursor. The Salesforce and Blackbaud families don't include a list-events endpoint today. Integrations using those families typically receive event IDs out-of-band (e.g. from the destination CRM) and call `/items`, `/purchases`, and `/guests` directly. A list-events endpoint for these families is **Coming Soon** — contact [support@givergy.com](mailto:support@givergy.com) if you need it. ## Bundle pagination caveat For `/items` and `/purchases`, the `offset` and `limit` parameters apply **per category** inside the bundle, not across the whole response. If you have more than 1000 records in any single category for an event, you must paginate by re-issuing the request with rising `offset` until every category returns an empty array. The bundle wrapper structure (the six keys) is constant; only the array contents shrink. For example, requesting `/items?offset=0&limit=1000` then `/items?offset=1000&limit=1000` returns rows 0–999 then rows 1000–1999 **of every category independently** — not "the next 1000 items across all categories." ## Recommended polling cadence | Event state | Suggested interval | | ------------------------------------------------ | ------------------ | | Active event (people are bidding / checking out) | Every few minutes | | Post-event reconciliation | Hourly | | Idle / historical sync | Less frequently | The shared rate-limit zone tolerates this comfortably. Avoid sub-second tight loops — see [Rate limiting](/events-auctions/rate-limiting) for the request-per-second target. ## Cursor storage Store `lastSyncTs` per resource per event, keyed however your sync job tracks state: ``` sync_state[event_id][resource] = max(updated) ``` If your job crashes partway through an event's resources, that resource's cursor stays at its previous value and the next run picks up where it left off. The `since` filter is inclusive of the cursor (`updated >= since`), so re-fetching a few overlapping records is harmless — your upsert logic should be idempotent anyway. ## When the `since` cursor isn't enough `since` only tracks changes, not deletions. The list endpoints implicitly filter to records with `status: "active"`, so a record being archived/obfuscated will simply stop appearing — your downstream copy won't see the change unless you periodically reconcile by listing all current records. For most reporting use cases, this is fine. If you need true deletion semantics, plan a periodic full reconciliation (e.g. weekly): list everything currently active, diff against your local copy, and mark anything missing as deleted on your side. # Rate limiting Source: https://developers.momogood.com/events-auctions/rate-limiting Plan for 1 request per second per integrator. Contact support@givergy.com to request a higher quota. ## Plan for 1 request per second Sustained polling on the order of **one request per second per integrator** is the typical traffic profile for these endpoints. Build your sync logic around that rate — most integrators sync every few minutes during an active event and every hour or so once events have closed. Need a higher quota? Contact [support@givergy.com](mailto:support@givergy.com) **before scaling up your traffic** so the team can review your use case and adjust your account's rate limits accordingly. ## When you exceed the rate limit If you push past the shared rate-limit zone, you'll see one of: | Status | When | | ------------------------------------- | --------------------------------------------------------------------------------------------- | | `429 Too Many Requests` | Short-term burst above the allowed rate. Back off and retry. | | `503 Service Temporarily Unavailable` | Sustained traffic above the rate-limit zone capacity, or an upstream component is overloaded. | In both cases, the right response is to **back off with exponential delay** before retrying. Avoid tight retry loops — they make the problem worse. If you see persistent `429`s or `503`s with normal traffic, that's a signal to contact [support@givergy.com](mailto:support@givergy.com) to discuss your traffic profile. ## Recommended polling cadence | Event state | Suggested polling interval | | ---------------------------------------------------------- | -------------------------- | | Active event (people are bidding / checking out right now) | Every few minutes | | Post-event reconciliation | Hourly | | Idle / historical sync | Less frequently | Avoid sub-second tight loops — they exhaust the rate-limit budget quickly and don't give the database time to commit incoming changes. ## Why concrete thresholds aren't published Rate-limit thresholds vary by region and infrastructure capacity, and are tuned periodically. Publishing exact numbers would create a moving target. **One request per second is the practical target** — if your integration needs to go higher, reach out and Givergy will work with you on a sustainable plan. # Response schemas Source: https://developers.momogood.com/events-auctions/schemas Event, ItemsBundle, PurchasesBundle, Guest, AddressDetail, and the enums returned across every endpoint. Reference for every record type returned by the Events & Auctions API. Where the Custom Data Export and connector variants differ, the Custom Data Export variant is the superset — connector variants omit some fields (see [Payload customization examples](/events-auctions/overview#payload-customization-examples) for the full comparison). Quick links: * [`Event` (Custom Data Export variant)](#event-custom-data-export-variant) * [`ItemsBundle`](#itemsbundle) — wrapper for items * [`BuyNowItem`](#buynowitem) · [`AuctionItem`](#auctionitem) · [`Pledge`](#pledge) · [`Raffle`](#raffle) · [`GliRaffle`](#gliraffle) · [`Ticket`](#ticket) · [`BidIncrement`](#bidincrement) * [Example `ItemsBundle` (Custom Data Export) response](#example-itemsbundle-custom-data-export-response) * [`PurchasesBundle`](#purchasesbundle) — wrapper for purchases * [Common purchase fields](#common-purchase-fields) · [`BuyNowPurchase`](#buynowpurchase) · [`AuctionBid`](#auctionbid) · [`RafflePurchase`](#rafflepurchase) · [`GliRafflePurchase`](#glirafflepurchase) · [`TicketPurchase`](#ticketpurchase) · [`Donation`](#donation) * [Example `PurchasesBundle` (Custom Data Export) response](#example-purchasesbundle-custom-data-export-response) * [`Guest` (Custom Data Export variant)](#guest-custom-data-export-variant) · [Connector guest variants](#guest-connector-variants-salesforce-and-blackbaud) * [`AddressDetail`](#addressdetail) * [Enums](#enums): [`Status`](#status-enum) · [`PaymentStatus`](#paymentstatus-enum) · [`ProcessorType`](#processortype-enum) · [`giftAidStatus`](#giftaidstatus-yesnoanswer) *** ## Event (Custom Data Export variant) Returned by [`GET //v1/events`](/events-auctions/endpoints/events). | Field | Type | Description | | ------------- | -------------- | ----------------------------------------------------------------------------- | | `id` | UUID | Event id. | | `name` | string | Event display name. | | `status` | enum string | One of [`Status`](#status-enum). All listed events are `"active"`. | | `inAidOf` | string \| null | Beneficiary description. | | `startTime` | long (epoch s) | Event start. | | `endTime` | long (epoch s) | Event end. | | `eventDate` | long (epoch s) | Headline event date used for sorting/display. | | `timezone` | string | IANA timezone id (e.g. `Europe/London`, `America/New_York`). | | `currency` | string | ISO 4217 currency code (`GBP`, `USD`, `CAD`, `AUD`, `HKD`). | | `created` | long (epoch s) | When the event was created. | | `updated` | long (epoch s) | When the event was last updated. | | `projectType` | string | EMS project type code (e.g. `auction`, `mixed`). **Custom Data Export only.** | | `externalId` | string \| null | Client-supplied external reference. **Custom Data Export only.** | > The Salesforce/Blackbaud `Event` variant (not returned by any documented endpoint today, but useful background) would omit `projectType` and `externalId`. *** ## ItemsBundle ```json theme={null} { "buyNows": [ BuyNowItem, ... ], "auctionItems": [ AuctionItem, ... ], "pledges": [ Pledge, ... ], "prizeDraws": [ Raffle, ... ], "gliRaffles": [ GliRaffle, ... ], "tickets": [ Ticket, ... ] } ``` `prizeDraws` holds standard `Raffle` records; `gliRaffles` is a separate list because GLI-regulated raffles have distinct compliance handling. The wrapper shape is identical across all three families; the difference is in the per-record fields (see [Payload customization examples](/events-auctions/overview#payload-customization-examples)). ### BuyNowItem | Field | Type | Description | | ------------------- | ---------------------------------- | --------------------------------------------------------------------- | | `id` | UUID | Item id. | | `eventId` | UUID | Parent event. | | `number` | string | Display / catalogue number. | | `title` | string | Item name. | | `price` | long | Unit price (minor units). | | `available` | int | Inventory remaining. | | `bought` | int | Quantity sold to date. | | `requirePayment` | boolean | Whether checkout enforces payment. | | `created` | long (epoch s) | Creation timestamp. | | `updated` | long (epoch s) | Last-update timestamp. | | `revenueStreamType` | string | EMS revenue stream code. *(Custom Data Export only)* | | `externalId` | string \| null | Client reference. *(Custom Data Export only)* | | `categories` | string\[] | Category tags. *(Custom Data Export only)* | | `irsSubcategory` | string\[] | IRS reporting subcategories. *(Custom Data Export only)* | | `startPrice` | long | Suggested / starting price (minor units). *(Custom Data Export only)* | | `increments` | [`BidIncrement`](#bidincrement)\[] | Pricing tiers, where applicable. *(Custom Data Export only)* | | `description` | string \| null | Long description. *(Custom Data Export only)* | | `termsDescription` | string \| null | T\&Cs text. *(Custom Data Export only)* | | `taxRate` | double \| null | Tax rate as decimal (`0.2` = 20%). *(Custom Data Export only)* | | `estimate` | long \| null | Estimated value (minor units). *(Custom Data Export only)* | The Salesforce/Blackbaud `BuyNowItem` variants include only the first 10 fields (down to `updated`). ### AuctionItem | Field | Type | Description | | ------------------- | ---------------------------------- | ---------------------------------------------------------------- | | `id` | UUID | Lot id. | | `eventId` | UUID | Parent event. | | `number` | string | Lot number. | | `title` | string | Lot title. | | `currentAmount` | long | Current top bid (minor units). | | `topBidder` | string \| null | Top bidder name. Null when anonymous. | | `topBidAnonymous` | boolean | Whether the top bid is anonymous. | | `created` | long (epoch s) | Creation timestamp. | | `updated` | long (epoch s) | Last-update timestamp. | | `revenueStreamType` | string | EMS revenue stream code. *(Custom Data Export only)* | | `externalId` | string \| null | Client reference. *(Custom Data Export only)* | | `categories` | string\[] | Category tags. *(Custom Data Export only)* | | `irsSubcategory` | string\[] | IRS reporting subcategories. *(Custom Data Export only)* | | `startPrice` | long | Opening bid (minor units). *(Custom Data Export only)* | | `increments` | [`BidIncrement`](#bidincrement)\[] | Bid increment tiers. *(Custom Data Export only)* | | `type` | string | Auction type code (e.g. `STANDARD`). *(Custom Data Export only)* | | `description` | string \| null | Description text. *(Custom Data Export only)* | | `termsDescription` | string \| null | T\&Cs text. *(Custom Data Export only)* | | `estimate` | long \| null | Estimated value (minor units). *(Custom Data Export only)* | ### Pledge Identical across all three families. | Field | Type | Description | | --------- | -------------- | ------------------------------------------------------ | | `id` | UUID | Pledge id. | | `eventId` | UUID | Parent event. | | `number` | string | Display number. | | `title` | string | Pledge title. | | `minimum` | long | Minimum donation (minor units). | | `fixed` | boolean | `true` = fixed donation amount; `false` = open amount. | | `created` | long (epoch s) | Creation timestamp. | | `updated` | long (epoch s) | Last-update timestamp. | ### Raffle | Field | Type | Description | | ------------------- | -------------------- | ---------------------------------------------------- | | `id` | string (UUID format) | Raffle id. | | `eventId` | UUID | Parent event. | | `number` | string | Display number. | | `title` | string | Raffle title. | | `price` | long | Ticket price (minor units). | | `available` | int | Tickets remaining. | | `bought` | int | Tickets sold. | | `requirePayment` | boolean | Whether checkout enforces payment. | | `created` | long (epoch s) | Creation timestamp. | | `updated` | long (epoch s) | Last-update timestamp. | | `revenueStreamType` | string | EMS revenue stream code. *(Custom Data Export only)* | Connector variants omit `revenueStreamType` only. ### GliRaffle All fields from [`Raffle`](#raffle), **plus** `externalId` (string | null, Custom Data Export only). GLI-regulated raffles (Gaming Laboratories International) are reported separately for compliance. Connector variants omit `revenueStreamType` and `externalId`. ### Ticket | Field | Type | Description | | ------------------- | -------------- | ---------------------------------------------------- | | `id` | UUID | Ticket type id. | | `eventId` | UUID | Parent event. | | `title` | string | Ticket name. | | `price` | long | Ticket price (minor units). | | `maxPerPurchase` | int | Per-order cap. | | `available` | int | Tickets remaining. | | `bought` | int | Tickets sold. | | `created` | long (epoch s) | Creation timestamp. | | `updated` | long (epoch s) | Last-update timestamp. | | `revenueStreamType` | string | EMS revenue stream code. *(Custom Data Export only)* | | `externalId` | string \| null | Client reference. *(Custom Data Export only)* | ### BidIncrement A single tier of a bid-increment ladder. | Field | Type | Description | | ----------- | --------- | ---------------------------------------------------------------------------------------------------------------- | | `threshold` | long (≥0) | Lower bound (minor units) at which this increment applies. `0` means the increment applies from the opening bid. | | `amount` | long (≥1) | The minimum bid step (minor units) when the current price is at or above `threshold`. | Some earlier Givergy reference material used `from` / `increment` for these field names. The actual JSON field names are `threshold` and `amount`. Trust this document over older examples. ### Example `ItemsBundle` (Custom Data Export) response ```json theme={null} { "buyNows": [ { "id": "b1a2c3d4-0001-4000-8000-000000000001", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "number": "BN-001", "title": "Signed Football", "price": 5000, "available": 8, "bought": 2, "requirePayment": true, "created": 1709200000, "updated": 1714100000, "revenueStreamType": "merchandise", "externalId": "EXT-BN-001", "categories": ["sports", "memorabilia"], "irsSubcategory": ["sports_collectibles"], "startPrice": 5000, "increments": [], "description": "Football signed by the 2025 squad.", "termsDescription": "No refunds.", "taxRate": 0.2, "estimate": 7500 } ], "auctionItems": [ { "id": "a1a2c3d4-0001-4000-8000-000000000001", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "number": "L-001", "title": "Weekend Stay in Paris", "currentAmount": 120000, "topBidder": "Jane Doe", "topBidAnonymous": false, "created": 1709200000, "updated": 1714200000, "revenueStreamType": "auction", "externalId": "EXT-L-001", "categories": ["travel"], "irsSubcategory": ["travel_packages"], "startPrice": 50000, "increments": [ { "threshold": 0, "amount": 5000 }, { "threshold": 100000, "amount": 10000 } ], "type": "STANDARD", "description": "Two nights at a 4-star hotel in central Paris.", "termsDescription": "Subject to availability.", "estimate": 150000 } ], "pledges": [ { "id": "p1a2c3d4-0001-4000-8000-000000000001", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "number": "PL-001", "title": "Sponsor a Meal", "minimum": 1000, "fixed": false, "created": 1709200000, "updated": 1709200000 } ], "prizeDraws": [ { "id": "r1a2c3d4-0001-4000-8000-000000000001", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "number": "PD-001", "title": "Win a Tesla", "price": 2500, "available": 500, "bought": 124, "requirePayment": true, "created": 1709200000, "updated": 1714050000, "revenueStreamType": "raffle" } ], "gliRaffles": [ { "id": "g1a2c3d4-0001-4000-8000-000000000001", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "number": "GLI-001", "title": "50/50 Draw", "price": 2000, "available": 1000, "bought": 312, "requirePayment": true, "created": 1709200000, "updated": 1714100000, "revenueStreamType": "gli_raffle", "externalId": "EXT-GLI-001" } ], "tickets": [ { "id": "t1a2c3d4-0001-4000-8000-000000000001", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "title": "Standard Entry", "price": 7500, "maxPerPurchase": 10, "available": 200, "bought": 47, "created": 1709200000, "updated": 1714000000, "revenueStreamType": "ticket", "externalId": "EXT-T-STD" } ] } ``` *** ## PurchasesBundle ```json theme={null} { "buyNowPurchases": [ BuyNowPurchase, ... ], "winningBids": [ AuctionBid, ... ], "donations": [ Donation, ... ], "rafflePurchases": [ RafflePurchase, ... ], "gliRafflePurchases": [ GliRafflePurchase, ... ], "ticketPurchases": [ TicketPurchase, ... ] } ``` All purchase records share a common set of fields. Each subtype adds a small number of type-specific fields. ### Common purchase fields | Field | Type | Description | | ------------------------- | -------------- | ------------------------------------------------------------------ | | `id` | UUID | Purchase id. | | `eventId` | UUID | Parent event. | | `guestId` | UUID | Guest who made the purchase. | | `guestName` | string | Guest display name. Empty string when anonymous. | | `anonymous` | boolean | Whether the guest chose to remain anonymous. | | `amount` | long | Gross amount (minor units). | | `count` | int | Quantity. Not present on `AuctionBid` (a winning bid is always 1). | | `totalFeesAmount` | long | Total fees retained from `amount`. | | `totalFeesPassedOnAmount` | long | Fees added on top, paid by the guest. | | `paymentProcessorId` | string \| null | Processor's transaction reference (e.g. Stripe payment intent id). | | `created` | long (epoch s) | Creation timestamp. | | `updated` | long (epoch s) | Last-update timestamp. | The following three fields are present **only on the Custom Data Export variants**. They are absent from every purchase record returned by the Salesforce and Blackbaud connector endpoints. | Field | Type | Description | | ---------------- | -------------- | -------------------------------------------------------------------------- | | `projectSegment` | string \| null | Reporting segment (free-form). *(Custom Data Export only)* | | `processorType` | enum | One of [`ProcessorType`](#processortype-enum). *(Custom Data Export only)* | | `paymentStatus` | enum | One of [`PaymentStatus`](#paymentstatus-enum). *(Custom Data Export only)* | ### Type-specific fields | Type | Wrapper key | Extra fields | | ----------------------------------------- | -------------------- | ---------------------------------------------------------------------------------------------- | | [`BuyNowPurchase`](#buynowpurchase) | `buyNowPurchases` | `buyNowItemId`, `buyNowItemTitle`, `supplyPrice` | | [`AuctionBid`](#auctionbid) | `winningBids` | `auctionItemId`, `auctionItemTitle`, `calculatedAmount`, `supplyPrice` (no `count` field) | | [`RafflePurchase`](#rafflepurchase) | `rafflePurchases` | `raffleId`, `raffleTitle`, `winningCount` | | [`GliRafflePurchase`](#glirafflepurchase) | `gliRafflePurchases` | `raffleId`, `raffleTitle`, `winningCount` | | [`TicketPurchase`](#ticketpurchase) | `ticketPurchases` | `ticketId`, `ticketTitle`, `ticketPurchaseRef`, `bookingFeeAmount`, `bookingFeePassedOnAmount` | | [`Donation`](#donation) | `donations` | `pledgeId`, `pledgeTitle`, `giftAidStatus` | ### BuyNowPurchase Common purchase fields plus: | Field | Type | Description | | ----------------- | ------ | ------------------------------ | | `buyNowItemId` | UUID | Reference to the `BuyNowItem`. | | `buyNowItemTitle` | string | Item title. | | `supplyPrice` | long | Cost of supply (minor units). | ### AuctionBid Common purchase fields plus: | Field | Type | Description | | ------------------ | ------ | -------------------------------------- | | `auctionItemId` | UUID | Reference to the `AuctionItem`. | | `auctionItemTitle` | string | Lot title. | | `calculatedAmount` | long | Calculated final amount (minor units). | | `supplyPrice` | long | Cost of supply (minor units). | **No `count` field** — a winning bid is always 1. ### RafflePurchase Common purchase fields plus: | Field | Type | Description | | -------------- | ------ | ------------------------------------------- | | `raffleId` | UUID | Reference to the `Raffle`. | | `raffleTitle` | string | Raffle title. | | `winningCount` | int | Number of winning tickets in this purchase. | ### GliRafflePurchase Same fields as `RafflePurchase`, returned under the `gliRafflePurchases` key. GLI raffles are reported separately for compliance. ### TicketPurchase Common purchase fields plus: | Field | Type | Description | | -------------------------- | ------ | ---------------------------------------------------------- | | `ticketId` | UUID | Reference to the `Ticket`. | | `ticketTitle` | string | Ticket name. | | `ticketPurchaseRef` | string | Human-readable booking reference (e.g. `TKT-2026-00047`). | | `bookingFeeAmount` | long | Booking fee retained (minor units). | | `bookingFeePassedOnAmount` | long | Booking fee added on top, paid by the guest (minor units). | ### Donation Common purchase fields plus: | Field | Type | Description | | --------------- | ----------- | ------------------------------------------------------------------------------- | | `pledgeId` | UUID | Reference to the `Pledge`. | | `pledgeTitle` | string | Pledge title. | | `giftAidStatus` | enum string | One of [`giftAidStatus`](#giftaidstatus-yesnoanswer): `not_asked`, `yes`, `no`. | ### Example `PurchasesBundle` (Custom Data Export) response ```json theme={null} { "buyNowPurchases": [ { "id": "c0000001-0000-4000-8000-000000000001", "buyNowItemId": "b1a2c3d4-0001-4000-8000-000000000001", "buyNowItemTitle": "Signed Football", "anonymous": false, "guestId": "f0000001-0000-4000-8000-000000000001", "guestName": "Alice Smith", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "amount": 5000, "count": 1, "totalFeesAmount": 150, "totalFeesPassedOnAmount": 0, "paymentProcessorId": "pi_3OabcDEFghi", "supplyPrice": 2000, "created": 1713900000, "updated": 1713900000, "projectSegment": "main", "processorType": "stripe", "paymentStatus": "paid" } ], "winningBids": [ { "id": "c0000002-0000-4000-8000-000000000002", "auctionItemId": "a1a2c3d4-0001-4000-8000-000000000001", "auctionItemTitle": "Weekend Stay in Paris", "anonymous": false, "guestId": "f0000002-0000-4000-8000-000000000002", "guestName": "Bob Jones", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "amount": 120000, "calculatedAmount": 120000, "totalFeesAmount": 3600, "totalFeesPassedOnAmount": 0, "paymentProcessorId": "pi_3OxyzABCdef", "supplyPrice": 60000, "created": 1714200000, "updated": 1714200000, "projectSegment": "main", "processorType": "stripe", "paymentStatus": "paid" } ], "donations": [ { "id": "c0000004-0000-4000-8000-000000000004", "pledgeId": "p1a2c3d4-0001-4000-8000-000000000001", "pledgeTitle": "Sponsor a Meal", "anonymous": false, "guestId": "f0000004-0000-4000-8000-000000000004", "guestName": "Carol White", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "amount": 2500, "count": 1, "totalFeesAmount": 75, "totalFeesPassedOnAmount": 0, "paymentProcessorId": "pi_3OdonLMNopq", "giftAidStatus": "yes", "created": 1714100000, "updated": 1714100000, "projectSegment": "main", "processorType": "stripe", "paymentStatus": "paid" } ], "rafflePurchases": [ { "id": "c0000003-0000-4000-8000-000000000003", "raffleId": "r1a2c3d4-0001-4000-8000-000000000001", "raffleTitle": "Win a Tesla", "winningCount": 0, "anonymous": true, "guestId": "f0000003-0000-4000-8000-000000000003", "guestName": "", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "amount": 5000, "count": 2, "totalFeesAmount": 0, "totalFeesPassedOnAmount": 150, "paymentProcessorId": "pi_3OrafFGHijk", "created": 1714050000, "updated": 1714050000, "projectSegment": "main", "processorType": "stripe", "paymentStatus": "paid" } ], "gliRafflePurchases": [ { "id": "c0000006-0000-4000-8000-000000000006", "raffleId": "g1a2c3d4-0001-4000-8000-000000000001", "raffleTitle": "50/50 Draw", "winningCount": 0, "anonymous": false, "guestId": "f0000006-0000-4000-8000-000000000006", "guestName": "Eve Green", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "amount": 4000, "count": 2, "totalFeesAmount": 0, "totalFeesPassedOnAmount": 120, "paymentProcessorId": "pi_3OgliWXYzab", "created": 1714100000, "updated": 1714100000, "projectSegment": "main", "processorType": "stripe", "paymentStatus": "paid" } ], "ticketPurchases": [ { "id": "c0000005-0000-4000-8000-000000000005", "ticketId": "t1a2c3d4-0001-4000-8000-000000000001", "ticketTitle": "Standard Entry", "ticketPurchaseRef": "TKT-2026-00047", "guestId": "f0000005-0000-4000-8000-000000000005", "guestName": "David Black", "eventId": "8f3c2a1d-9b4e-4c7a-a1d2-6e5f4c3b2a10", "amount": 15000, "count": 2, "bookingFeeAmount": 0, "bookingFeePassedOnAmount": 450, "totalFeesAmount": 450, "totalFeesPassedOnAmount": 450, "paymentProcessorId": "pi_3OtktRSTuvw", "created": 1713800000, "updated": 1713800000, "projectSegment": "main", "processorType": "stripe", "paymentStatus": "paid" } ] } ``` > A Salesforce or Blackbaud `/purchases` response would be **the same shape**, but every record would have `projectSegment`, `processorType`, and `paymentStatus` removed. *** ## Guest (Custom Data Export variant) Returned by the Custom Data Export `/guests` endpoint. | Field | Type | Description | | ---------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------- | | `id` | UUID | Guest (contact) id. | | `eventId` | UUID | Parent event. | | `firstName` | string \| null | First name. | | `lastName` | string \| null | Last name. | | `email` | string \| null | Email address. | | `mobile` | string \| null | Mobile phone. May be E.164 or local format depending on how it was captured. | | `mainAddress` | [`AddressDetail`](#addressdetail) \| null | Primary postal address. | | `giftAidAddress` | [`AddressDetail`](#addressdetail) \| null | Gift Aid declaration address (UK). | | `taxReceiptAidAddress` | [`AddressDetail`](#addressdetail) \| null | Tax-receipt address (US). | | `created` | long (epoch s) | Creation timestamp. | | `updated` | long (epoch s) | Last-update timestamp. | | `consentAsked` | boolean | Whether the guest has been prompted for consent. | | `consentStatus` | enum string | One of [`Status`](#status-enum); typically `"active"` or `"inactive"` for consent records. | | `consentChannels` | string | Comma-separated channels the guest has opted in to (e.g. `email,sms,post`). Empty string when none. | | `externalId` | string \| null | Client reference. *(Custom Data Export only)* | | `smsOptIn` | boolean | SMS opt-in flag. *(Custom Data Export only)* | | `companyName` | string \| null | Company / organisation name. *(Custom Data Export only)* | ### Guest connector variants (Salesforce and Blackbaud) `SalesforceGuest` (returned by `/salesforce/v1/.../guests`) and `BlackbaudGuest` (returned by `/blackbaud/v1/.../guests`) are **identical to each other** and contain every field from the Custom Data Export `Guest` **except** `externalId`, `smsOptIn`, and `companyName`. If you need any of those three fields, you must use the Custom Data Export `/guests` endpoint. *** ## AddressDetail | Field | Type | Description | | ---------------- | -------------- | -------------------------------------------------------------------- | | `name` | string \| null | Label (e.g. `Home`, `Billing`). | | `line1` | string \| null | First address line. | | `line2` | string \| null | Second address line. | | `line3` | string \| null | Third address line. | | `line4` | string \| null | Fourth address line. | | `town` | string \| null | Town / city. | | `postcode` | string \| null | Postal / ZIP code. | | `state` | string \| null | State / province / region. | | `country` | string \| null | ISO 3166-1 alpha-2 country code (e.g. `GB`, `US`, `CA`, `AU`, `HK`). | | `recipient_name` | string \| null | Recipient name. | Note the snake\_case spelling: the field is `recipient_name`, not `recipientName`. This is the only snake\_case field across these schemas. *** ## Enums All enum values are serialized in **lowercase** in JSON. See [Conventions → Enum casing](/events-auctions/conventions#enum-casing). ### Status enum Returned for `Event.status` and `Guest.consentStatus`. Values: `error`, `archived`, `active`, `inactive`, `not_archived`, `obfuscated`, `pending` In practice list endpoints only ever return records with `status: "active"` because of the implicit active-only filter. ### PaymentStatus enum Returned on Custom Data Export purchase records only. | Value | Meaning | | -------------------- | -------------------------------------------------- | | `unknown` | Status not yet determined. | | `paid` | Payment captured in full. | | `unpaid` | Awaiting payment. | | `part_paid` | Partial payment received. | | `retracted` | Payment retracted. | | `overpaid` | Payment exceeds the amount due. | | `processor_pending` | Processor is still processing the payment. | | `processor_declined` | Processor declined the payment. | | `user_canceled` | Guest cancelled before payment. | | `split` | Amount split across multiple records / processors. | | `pay_later` | Payment deferred (will settle later). | For most reporting use cases, treat `paid`, `part_paid`, `overpaid`, and `split` as "money received." ### ProcessorType enum Returned on Custom Data Export purchase records only. `none`, `paypal`, `paypal_here`, `cheque_client`, `cheque_ibid`, `cash_client`, `cash_ibid`, `bank_transfer_client`, `bank_transfer_ibid`, `braintree`, `braintree_amex`, `braintree_vt`, `braintree_vt_amex`, `stripe`, `daf_pay`, `stripe_amex`, `stripe_vt`, `stripe_vt_amex`, `pdq`, `pdq_amex`, `eftpos`, `amex`, `zero_amount_charge`, `free` Conventions: * The `_vt` suffix indicates a virtual terminal (typed-in card). * `_client` variants indicate funds collected directly by the client. * `_ibid` variants indicate funds collected by Givergy on the client's behalf. ### giftAidStatus (YesNoAnswer) `Donation.giftAidStatus` is a tri-state string answering "has the guest agreed to Gift Aid this donation?" | Value | Meaning | | ----------- | ------------------------------------------------------------ | | `not_asked` | The guest has not been asked, or Gift Aid is not applicable. | | `yes` | Guest has agreed and a Gift Aid declaration is on file. | | `no` | Guest has declined Gift Aid. | Earlier Givergy reference material listed values like `CLAIMED`, `PENDING`, `NOT_REQUESTED`. Those are incorrect — the wire values are the three above. Gift Aid is a UK-only HMRC mechanism, so this field is most meaningful for UK events. # Build with momoGood Source: https://developers.momogood.com/index One ecosystem. Three product APIs. A unified developer experience for charities, donors, and the events they run.
momoGood developer platform · v1

Build with momoGood.
One ecosystem. Three product APIs.

Reach donors over SMS, run gala auctions, and pull unified analytics — each through its own purpose-built API. We keep the systems separate so each one stays great. We unify the developer experience so you only learn it once.

Start building All systems operational

Choose a product

Each API has its own routes, auth model, and operational SLAs. Click in to browse the reference.

How the platform fits together

Each product API is its own service with its own routes and SLAs. They share a developer portal, a single brand, and a small set of conventions — not a backend.

One developer ecosystem, multiple product APIs. Not a unified backend — each system below preserves its own routes, auth, and operational model.
Your app
Integration
CRM, warehouse, ETL, internal tool
Messaging
api.momogood.com/messaging/v2
HTTP Basic · REST
Events & Auctions
api.momogood.com/events/v1
Service user · Polling
Data Hub
api.momogood.com/datahub/v1
OAuth 2.0 · Scoped
3
Product APIs
58
Endpoints
99.97%
12-mo uptime
8
Webhook events
# Introduction Source: https://developers.momogood.com/messaging/message-sending-api-reference/introduction Get started with the momoGood Messaging API v3 Welcome to the momoGood Messaging API v3 (formerly the Tatango Message Sending API) — purpose-built for high-throughput omnichannel message sending across SMS, MMS, RCS, and WhatsApp. It's optimized for performance-sensitive delivery workloads where speed, reliability, and channel breadth matter most. Need to manage lists, subscribers, custom fields, webhooks, or scheduled broadcasts? Use the [momoGood Messaging API v2](/messaging/v2-api-reference/introduction) — the platform management API for momoGood Messaging. ## Base URL The momoGood Messaging API v3 is built on REST principles. We enforce HTTPS in every request to improve data security, integrity, and privacy. The API does not support HTTP. All requests contain the following base URL: ```bash theme={null} https://api.v3.tatango.com ``` ## Authentication To authenticate you need to add the `x-api-key` header populated with your momoGood-provided API key *shown in the GIF below*. ```bash theme={null} x-api-key: tatango_key_xxxxxxxxx ``` ### API Key Creation You can create an API key by logging into the [momoGood Messaging app](https://app.tatango.com/login) and navigating to My Account -> API -> Create API Key. GIF showing the process of creating an API key in the momoGood Messaging app interface ## Response Codes The momoGood Messaging API v3 uses standard HTTP codes to indicate the success or failure of your requests. In general, 2xx HTTP codes correspond to success, 4xx codes are for user-related failures, and 5xx codes are for infrastructure issues. | Status | Description | | ------ | ------------------------------------------------------------------------------------------------------- | | 200 | Successful request. | | 202 | Successful request, and the request is being processed asynchronously. | | 400 | Check that the request body's parameters were correct. | | 403 | The API key used was invalid or missing. | | 404 | The resource was not found. Check the URL and HTTP method. | | 429 | The rate limit was exceeded. | | 5xx | Indicates an error with momoGood servers. If you receive this error repeatedly, please contact support. | Specific error information is available for each request. This is shown on the request's page. See the "response" sub-section at the bottom of the page for an [example](/messaging/message-sending-api-reference/sms/send-sms#response-error). Then, click the drop down to see the specific error response examples. ## Rate Limit The default rate limit is 10 requests per second. This number can be increased for trusted senders by request. After that, you'll hit the rate limit and receive a 429 response error code. Learn more about our [rate limits](/messaging/message-sending-api-reference/rate-limit). # Send an MMS Message Source: https://developers.momogood.com/messaging/message-sending-api-reference/mms/send-mms POST /transactional_messages/send_mms This endpoint allows you to send an MMS message to a U.S. or Canadian phone number. If delivery fails, a fallback SMS message will be sent. You can use any publicly accessible URL for attachments, or upload them via the momoGood Messaging app's [attachments page](https://app.tatango.com/attachments). **File Size Limits:** * **Shortcodes:** Images (1MB), GIFs (0.6MB), Videos (2MB) * **10DLC:** All files (0.75MB) **Supported File Types:** JPG, JPEG, PNG, GIF, WebP, MP4, MPEG, vCard # Rate Limits Source: https://developers.momogood.com/messaging/message-sending-api-reference/rate-limit Understanding API rate limits and best practices ## Overview The momoGood Messaging API v3 (formerly the Tatango Message Sending API) implements rate limiting to ensure fair usage of our API resources and maintain service stability. The rate limit is applied on a per-API key basis. ## Default Limits * **Default Rate**: 10 requests per second * **Reset Period**: Every one second * **Daily Quota**: 10,000 requests per day, reset at midnight UTC For trusted senders with higher volume needs, these limits can be increased upon request. Contact our support team to discuss your specific requirements. ## Handling Rate Limits When you exceed the rate limit, the API will respond with a 429 HTTP status code (Too Many Requests). It is recommended to implement exponential backoff with jitter to prevent thundering herd problems. ### Rate Limit Response Example ```http theme={null} HTTP/1.1 429 Too Many Requests Content-Type: application/json x-amzn-RequestId: 5f4e1d2a-1234-5678-9abc-def012345678 x-amz-apigw-id: abc123XYZ= x-amzn-ErrorType: TooManyRequestsException { "message": "Too Many Requests" } ``` ### Exponential Backoff with Jitter Example Here's an example of handling rate limits with exponential backoff in JavaScript: ```javascript theme={null} async function makeRequestWithRetry(url, options, maxRetries = 3) { const baseDelay = 1000; // Base delay of 1 second const maxDelay = 32000; // Maximum delay of 32 seconds for (let attempt = 0; attempt < maxRetries; attempt++) { try { const response = await fetch(url, options); if (response.status === 429) { // Calculate exponential backoff const exponentialDelay = Math.min( baseDelay * Math.pow(2, attempt), maxDelay ); // Add random jitter (between 0-100% of the delay) const jitter = Math.random() * exponentialDelay; const totalDelay = exponentialDelay + jitter; console.log(`Rate limited. Retrying in ${Math.round(totalDelay/1000)} seconds...`); await new Promise(resolve => setTimeout(resolve, totalDelay)); continue; } return response; } catch (error) { if (attempt === maxRetries - 1) throw error; } } } ``` ## Increased Rate Limits If you need higher rate limits, we offer increased limits for trusted senders. To request an increase: 1. Contact our support team. 2. Provide your use case and expected request volume. 3. We'll review your request and adjust limits accordingly. Remember that even with increased limits, it's important to implement proper rate limit handling in your code to ensure reliable operation. # Send an RCS Text Message Source: https://developers.momogood.com/messaging/message-sending-api-reference/rcs/send-rcs POST /transactional_messages/send_rcs_text This endpoint allows you to send an RCS (Rich Communication Services) text message to a U.S. phone number. If delivery fails, a fallback SMS message will be sent. RCS (Rich Communication Services) provides enhanced messaging features compared to SMS and MMS. **RCS Message Features:** * **Character Limit:** Up to 3,000 characters * **Rich Text Features:** Bold, italic, underline, strikethrough and emojis * **Fallback:** Automatic SMS fallback if RCS delivery fails **Requirements:** Valid U.S. phone number with RCS support # Send an RCS Carousel Source: https://developers.momogood.com/messaging/message-sending-api-reference/rcs/send-rcs-carousel POST /transactional_messages/send_rcs_carousel This endpoint allows you to send an RCS Carousel message with multiple rich cards to a U.S. phone number. If delivery fails, a fallback SMS message will be sent. RCS Carousels allow you to send multiple rich cards in a single message, creating an interactive sliding experience. **RCS Carousel Features:** * **Multiple Cards:** Send 1-3 rich cards in a single message * **Media Support:** Images and videos with thumbnails * **Rich Text:** Rich text features: Bold, italic, underline, strikethrough and emojis * **Fallback:** Automatic SMS fallback if RCS delivery fails **Requirements:** Valid U.S. phone number with RCS support # Send an RCS File Source: https://developers.momogood.com/messaging/message-sending-api-reference/rcs/send-rcs-file POST /transactional_messages/send_rcs_file This endpoint allows you to send an RCS File message with file attachment to a U.S. phone number. If delivery fails, a fallback SMS message will be sent. RCS File messages allow you to send file attachments with optional action buttons for enhanced user interaction. **RCS File Features:** * **File Support:** Send various file types as attachments, notably PDF and audio files * **Rich Experience:** Enhanced file sharing with interactive elements * **Fallback:** Automatic SMS fallback if RCS delivery fails **Requirements:** Valid U.S. phone number with RCS support # Send an RCS Rich Card Source: https://developers.momogood.com/messaging/message-sending-api-reference/rcs/send-rcs-rich-card POST /transactional_messages/send_rcs_rich_card This endpoint allows you to send an RCS Rich Card message with media to a U.S. phone number. If delivery fails, a fallback SMS message will be sent. RCS Rich Cards provide interactive messaging experiences with media, text, and action buttons. **RCS Rich Card Features:** * **Media Support:** Images and videos with thumbnails * **Rich Text:** Rich text features: Bold, italic, underline, strikethrough and emojis * **Fallback:** Automatic SMS fallback if RCS delivery fails **Requirements:** Valid U.S. phone number with RCS support # Send an SMS Message Source: https://developers.momogood.com/messaging/message-sending-api-reference/sms/send-sms POST /transactional_messages/send_sms This endpoint allows you to send an SMS message to a U.S. or Canadian phone number. # Delivery Status Source: https://developers.momogood.com/messaging/message-sending-api-reference/webhooks/delivery-status webhook delivery_status This webhook is called when a message is successfully or unsuccessfully delivered. # Invalid Phone Source: https://developers.momogood.com/messaging/message-sending-api-reference/webhooks/invalid-phone webhook invalid_phone This webhook is called when a phone number is determined to be invalid during validation. # Reply Received Source: https://developers.momogood.com/messaging/message-sending-api-reference/webhooks/reply-received webhook reply_received This webhook is called when a recipient replies to a sent message. # Send a WhatsApp Template Message Source: https://developers.momogood.com/messaging/message-sending-api-reference/whatsapp/send-whatsapp POST /transactional_messages/send_whatsapp This endpoint allows you to send a WhatsApp Templated Message along with an SMS Fallback. The SMS Fallback is used if the WhatsApp message fails to deliver. # Upload a WhatsApp Template Source: https://developers.momogood.com/messaging/message-sending-api-reference/whatsapp/upload-whatsapp-template POST /whatsapp_template/upload This endpoint allows you to upload a new WhatsApp template for approval. # Get Current Account Source: https://developers.momogood.com/messaging/v2-api-reference/accounts/get-current-account GET /api/v2/accounts/me This endpoint retrieves the current account, as specified by the API key used to authenticate. ```http theme={null} GET https://app.tatango.com/api/v2/accounts/me ``` # Create a Custom Field Source: https://developers.momogood.com/messaging/v2-api-reference/custom-fields/create-custom-field POST /api/v2/lists/{ID}/custom_field This endpoint creates a custom field. ## Request URL ```http theme={null} POST https://app.tatango.com/api/v2/lists//custom_field ``` # Deleting a Custom Field Source: https://developers.momogood.com/messaging/v2-api-reference/custom-fields/deleting-custom-field DELETE /api/v2/lists/{ID}/custom_fields This endpoint deletes a custom field. ## Request URL ```http theme={null} DELETE https://app.tatango.com/api/v2/lists//custom_fields ``` # Get a List of Custom Fields Source: https://developers.momogood.com/messaging/v2-api-reference/custom-fields/get-list-of-custom-fields GET /api/v2/lists/{ID}/custom_fields This endpoint fetches a list of Custom Fields. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists//custom_fields ``` # Introduction Source: https://developers.momogood.com/messaging/v2-api-reference/introduction Get started with the momoGood Messaging API v2 Welcome to the momoGood Messaging API v2 (formerly the Tatango v2 API) — the platform management API for momoGood Messaging. Use it to manage lists, subscribers, custom fields, tags, webhooks, shortcodes, MOMT reports, and scheduled broadcasts from a single REST surface. It's designed for developers, engineers, or anyone else who's comfortable creating custom-coded solutions or integrating with RESTful APIs. If you're not familiar with API concepts like HTTP response codes, REST endpoints, and JSON, try Zapier. Looking for high-throughput omnichannel sending across SMS, MMS, RCS, and WhatsApp? See the [momoGood Messaging API v3](/messaging/message-sending-api-reference/introduction) — purpose-built for performance-sensitive delivery workloads. ## Authentication The momoGood Messaging API v2 authenticates requests by validating an API key that must be passed with each API call. We use the built-in HTTP basic authentication scheme supported by most HTTP libraries. Use your login email as the username and the API key as the password. ```bash theme={null} curl -u "your_email@example.com:your_api_key" https://app.tatango.com/api/v2/lists ``` ```ruby theme={null} require 'net/http' require 'uri' uri = URI.parse('https://app.tatango.com/api/v2/example-endpoint') http = Net::HTTP.new(uri.host, uri.port) request = Net:HTTP::Get.new(uri.request_url) request.basic_auth("emailaddress@mydomain.com", "my_api_key") response = http.request(request) ``` ```javascript theme={null} var request = new XMLHttpRequest(); request.open("POST", "https://app.tatango.com/api/v2/example-endpoint", false); request.setRequestHeader("Content-Type", "application/json"); request.setRequestHeader("Content-Type", "application/json"); request.setRequestHeader( "Authorization", "Basic " + btoa("emailaddress@mydomain.com:my_api_key") ); request.send(null);; ``` Make sure to replace my\_api\_key with your API key, which can be obtained by logging into the [momoGood Messaging app](https://app.tatango.com). You can access your API key [here](http://help.tatango.com/api/api-keys). ## Returning multiple results and pagination By default, `GET` API calls that return multiple items in a list will return up to 10 items for a single call. The `pages_count` parameter in the returned JSON will indicate the number of "pages" included in the entire result set. (So for example, if a call to [https://app.tatango.com/api/v2/lists](https://app.tatango.com/api/v2/lists) finds 27 lists in the system, the JSON will include the following (see JSON snippet below): ```json theme={null} { "per_page":10, "count":27, "page":1, "pages_count":3 } ``` The `pages_count` parameter will default to 0 when there is no items in the list. To fetch the next page of results, pass the `page` parameter on the URL, like this: [https://app.tatango.com/api/v2/lists?page=2](https://app.tatango.com/api/v2/lists?page=2). You can also change the number of records returned in each "page" by passing in a "per\_page" parameter as part of the URL, like this: [https://app.tatango.com/api/v2/lists?per\_page=50](https://app.tatango.com/api/v2/lists?per_page=50). Note that the system will only allow up to 1000 records to be returned in a single call. ## Carrier IDs This section provides a list of carrier ID and names (US and Canada) for any response that includes `carrier` and `carrierName`. ### United States Carriers | Carrier Name | Carrier ID | | -------------------------------------------- | ---------- | | 1st Point (a.k.a. Shelcomm) | 11293 | | Aerialink | 11333 | | Alaska Communications Systems (ACS) | 592 | | Altice Mobile | 11359 | | ASTAC | 10242 | | AT\&T | 383 | | Atlantic Tele-Network International (ATNI) | 10542 | | bandwidth.com (includes Republic Wireless) | 766 | | Bluegrass Cellular | 562 | | Boost | 628 | | Brightlink | 10212 | | Bristol Bay Telephone Cooperative | 11332 | | C Spire Wireless (aka Cellular South) | 386 | | Carolina West Wireless | 564 | | Cellcom | 587 | | Cellular One of N.E. Arizona | 566 | | Chariton Valley Cellular | 701 | | Chat Mobility | 619 | | Copper Valley Telecom | 802 | | Cordova | 10282 | | Cross Wireless | 618 | | Digital Communications Consulting | 11316 | | DISH Wireless | 12227 | | Duet Wireless | 696 | | East Kentucky Network (Appalachian Wireless) | 570 | | Enflick | 10262 | | GCI Communications | 603 | | Google Voice | 798 | | Illinois Valley Cellular | 574 | | Indigo Wireless | 11174 | | Inland Cellular | 575 | | Inteliquent | 10232 | | ISP Telecom | 12228 | | James Valley Cellular (JVC) | 11304 | | MetroPCS | 788 | | MTPCS Cellular One (Cellone Nation) | 655 | | Nemont CDMA | 796 | | Nemont UMTS | 873 | | Nex Tech Communications | 578 | | Northwest Missouri Cellular | 620 | | Panhandle Wireless | 626 | | Pine Belt | 10352 | | Pine Cellular | 580 | | Pioneer Cellular | 621 | | Plivo | 11620 | | Ring Central | 11638 | | Rural Independent Network Alliance (RINA) | 567 | | SouthernLINC | 763 | | Sprint | 34 | | Standing Rock Telecom | 764 | | T-Mobile | 79 | | Telnyx | 11351 | | TextMe | 11306 | | Thumb Cellular | 604 | | Tracfone | 556 | | Triangle Wireless | 10272 | | Truphone | 11318 | | TSG Global (Flex Talk) | 11671 | | Tychron | 12227 | | Union Telephone | 549 | | United States Cellular Corp | 56 | | United Wireless | 602 | | Verizon | 77 | | Viaero Wireless | 650 | | Virgin Mobile | 525 | | West Central Wireless | 559 | | Zipwhip | 11749 | ### Canadian Carriers | Carrier Name | Carrier ID | | ----------------- | ---------- | | Aliant | 509 | | Bell Mobility | 80 | | Eastlink Wireless | 799 | | Execulink | 10573 | | Fido (Microcell) | 138 | | Fizz | 10638 | | Freedom / Wind | 653 | | Mobilicity | 654 | | MTS | 510 | | NorthernTel | 512 | | Rogers | 75 | | Sasktel | 102 | | SSI Micro | 11315 | | Telebec | 511 | | Telus | 70 | | Videotron | 615 | | Virgin Mobile | 537 | ## Errors The momoGood Messaging API v2 uses the following error codes: | Error Code | Meaning | | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 400 | Bad Request -- Your request is invalid. | | 401 | Unauthorized -- Your API key is wrong. | | 403 | Forbidden -- You are not authorized for this request. | | 404 | Not Found -- The specified endpoint could not be found. | | 405 | Method Not Allowed -- You tried to access an endpoint with an invalid method. | | 406 | Not Acceptable -- You requested a format that isn't JSON. | | 410 | Gone -- The requested resource has been removed from our servers. | | 422 | Unprocessable Entity - There was a problem of some sort with either the JSON or request parameters you supplied. Usually, this error will be accompanied by a detailed description of the problem. | | 429 | Too Many Requests -- You're requesting too many resources! Slow down! | | 500 | Internal Server Error -- We had a problem with our server. Try again later. | | 502 | Bad Gateway -- We had a problem with our server. Try again later. | | 503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. | # Configure List Opt-In Type Source: https://developers.momogood.com/messaging/v2-api-reference/lists/configure-list-opt-in-type PUT /api/v2/lists/{ID}/opt_in_settings This endpoint configures an opt-in type for a list. ## Request URL ```http theme={null} PUT https://app.tatango.com/api/v2/lists//opt_in_settings ``` # Creating a New List Source: https://developers.momogood.com/messaging/v2-api-reference/lists/creating-a-new-list POST /api/v2/lists/ This endpoint creates a new list. Note: the following settings cannot be modified via the API: * API Confirmation Resend Block Timeout * Resubscribers ### FAQs **What are the limitations for a keyword?** * A keyword must contain at least two characters and no more than 15 characters. * Keywords are not case sensitive. `FOO` will match `foo`, `FOO`, and `Foo`. * You can't use obscene words. We're not going to spell them out here. **Are keywords case sensitive?** * No. The system checks for duplicate keywords by transforming all keywords to uppercase before performing matching algorithms. **What happens if the keyword isn't available?** * The response from the API will be a 422 error with the response body looking like this: ```json theme={null} {"status":"error","error":"invalid keyword names: EXISTINGKW"} ``` **Can I check if a keyword is available?** * Yes. By utilizing this endpoint. The response will either be: ```json theme={null} {"status":"OK","keyword_name":"available"} ``` or ```json theme={null} {"status":"OK","keyword_name":"unavailable","error":"Name is in use"} ``` **Can I add multiple keywords to a list?** * Yes. The `keyword_names` parameter would need to be an array, like this: ```json theme={null} {"keyword_names":["TEST","KEYWORD","NAMES"]} ``` **What is a REPLY Response?** * REPLY Response is the response sent to the subscriber if they respond to the message with the word `REPLY`. ## Request URL ```http theme={null} POST https://app.tatango.com/api/v2/lists/ ``` # Destroying a List Source: https://developers.momogood.com/messaging/v2-api-reference/lists/destroying-a-list DELETE /api/v2/lists/{ID} This endpoint destroys a list. ## Request URL ```http theme={null} DELETE https://app.tatango.com/api/v2/lists/ ``` # List All Lists Source: https://developers.momogood.com/messaging/v2-api-reference/lists/list-all-lists GET /api/v2/lists This endpoint retrieves a list of all lists owned by the current account. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists ``` # Retrieve List Source: https://developers.momogood.com/messaging/v2-api-reference/lists/retrieve-list GET /api/v2/lists/{ID} This endpoint retrieves a specific list. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists/ ``` # Setting Keywords for a List Source: https://developers.momogood.com/messaging/v2-api-reference/lists/setting-keywords-for-list PUT /api/v2/lists/{ID}/keywords This endpoint sets or updates keywords for a list. ```http theme={null} PUT https://app.tatango.com/api/v2/lists//keywords ``` # Updating a List Source: https://developers.momogood.com/messaging/v2-api-reference/lists/updating-a-list PUT /api/v2/lists/{ID} This endpoint updates a list. ## Request URL ```http theme={null} PUT https://app.tatango.com/api/v2/lists/ ``` The following settings cannot be modified via the API: * API Confirmation Resend Block Timeout * Resubscribers # Querying an Existing Message Source: https://developers.momogood.com/messaging/v2-api-reference/messaging/querying-an-existing-message GET /api/v2/lists/{ID}/messages/{MESSAGE_ID} This endpoint retrieves a message. **Please note the following:** * It takes some time after a message is sent to receive delivery status notifications from the various carriers. We recommend waiting until at least 10 minutes after a message is sent to query for delivery statistics. * The `message_links` attribute will only be present on messages that have bit.ly links in their content. * The `parts` attribute will be available 30 minutes after the message was sent. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists/{ID}/messages/{MESSAGE_ID} ``` # Retrieve All Draft Messages in a List Source: https://developers.momogood.com/messaging/v2-api-reference/messaging/retrieve-all-draft-messages-in-list GET /api/v2/lists/{ID}/messages/draft This endpoint retrieves all draft messages in a list. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists/{ID}/messages/draft ``` # Retrieve All Scheduled Messages in a List Source: https://developers.momogood.com/messaging/v2-api-reference/messaging/retrieve-all-scheduled-messages-in-list GET /api/v2/lists/{ID}/messages/scheduled This endpoint retrieves all scheduled messages in a list. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists/{ID}/messages/scheduled ``` # Retrieve All Sent Messages in a List Source: https://developers.momogood.com/messaging/v2-api-reference/messaging/retrieve-all-sent-messages-in-list GET /api/v2/lists/{ID}/messages This endpoint retrieves all sent messages in a list. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists/{ID}/messages ``` **Please note the following:** * The `message_links` attribute will only be present on messages that have bit.ly links in their content. * The `tracking_links` attribute will only be present on messages that have tracking links in their content. * The `parts` attribute will be available 30 minutes after the message was sent. # Send Message to Entire List Source: https://developers.momogood.com/messaging/v2-api-reference/messaging/sending-message-to-entire-list POST /api/v2/lists/{ID}/messages This endpoint sends a message. ## Request URL ```http theme={null} POST https://app.tatango.com/api/v2/lists/{ID}/messages ``` # Creating a New MOMT Report Source: https://developers.momogood.com/messaging/v2-api-reference/momt-reports/creating-a-new-momt-report POST /api/v2/momt_reports This endpoint creates a new MOMT Report. ## Request URL ```http theme={null} POST https://app.tatango.com/api/v2/momt_reports ``` # Getting Status of a Processed MOMT Report Source: https://developers.momogood.com/messaging/v2-api-reference/momt-reports/get-status-of-momt-report GET /api/v2/momt_reports/{ID} This endpoint gets the status of a processed MOMT Report. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/momt_reports/{ID} ``` # Getting Status of a Unprocessed MOMT Report Source: https://developers.momogood.com/messaging/v2-api-reference/momt-reports/get-status-of-unprocessed-momt-report GET /api/v2/momt_reports/{ID}/unprocessed This endpoint gets the status of an unprocessed MOMT Report. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/momt_reports/{ID} ``` # Rate Limits Source: https://developers.momogood.com/messaging/v2-api-reference/rate-limit Understanding API rate limits and best practices The momoGood Messaging API v2 (formerly the Tatango v2 API) allows 1200 calls per hour or 1 call every 3 seconds. Please contact your account manager with your specific use case if you need a bump to this limit. # Listing Account Shortcodes Source: https://developers.momogood.com/messaging/v2-api-reference/shortcodes/listing-account-shortcodes GET /api/v2/shortcodes This endpoint gets a list of shortcodes provisioned on your account. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/shortcodes ``` # Testing Keyword Availability on Shortcode Source: https://developers.momogood.com/messaging/v2-api-reference/shortcodes/testing-keyword-availability POST /api/v2/shortcodes/{ID}/test_keyword This endpoint checks the availability of a keyword on the account's shortcode. ## Request URL ```http theme={null} POST https://app.tatango.com/api/v2/shortcodes/{ID}/test_keyword ``` ### FAQs **What are the limitations for a keyword?** * A keyword must contain at least two characters and no more than 15 characters. * Keywords are not case sensitive. `FOO` will match `foo` and `FOO` and `Foo`. * You can't use obscene words. We're not going to spell them out here. **Are keywords case sensitive?** * No. The system checks for duplicate keywords by transforming all keywords to uppercase before performing matching algorithms. **What happens if the keyword isn't available?** * The response from the API will be a 422 error with the response body looking like this: * `{"status":"error","error":"invalid keyword names: EXISTINGKW"}` **What happens if the keyword isn't available?** * Yes. By utilizing this endpoint. The response will either be: * `200 OK` with the response body looking like this: `{"status":"OK","keyword_name":"available"}` * `200 OK` with the response body looking like this: `{"status":"OK","keyword_name":"unavailable","error":"Name is in use"}`. # Adding a Subscriber Source: https://developers.momogood.com/messaging/v2-api-reference/subscribers/adding-a-subscriber POST /api/v2/lists/{ID}/subscribers This endpoint adds a subscriber to a list. The following parameters can be used to bypass the opt-in process: * `bypass_opt_in_process` - When true, adds phone number without double opt-in * `bypass_opt_in_response` - When true, suppresses confirmation message ### FAQs **What happens when we use the add subscriber API to add a home phone number (i.e. non-cellular)?** * You will receive the message "Bad phone number: landline or unreachable carrier" with the status code 422. **What happens when we use the add subscriber API to add a phone number that is currently unsubscribed from the list?** * We will initiate the process of resubscribing the phone number to the list. **What happens when we use the add subscriber API to add a phone number that is already subscribed to the list?** * A 200 OK is returned and no changes are made to the subscriber. **Can I request something other than a reply of YES to opt-in when opting into an API?** * No. The reply is currently configured to YES. **Can I add a subscriber via API with custom data for that subscriber?** * Yes. The optional parameters are listed for this API endpoint. **For subscriber fields like name, birthday, etc., are there any limitations on what we can use, like character limit, only certain characters, etc?** * Yes. All optional parameters' limitations are noted - see the JSON parameters above. **In what format should phone numbers be sent?** * The phone number should be a continuous string of ten digits - with no dashes and no country code (e.g. "2065551111"). **If an account has multiple lists, and a phone number has opted-out, or been cleaned from one list, can we use the API to add them to a new list?** * Yes - each list is a separate entity. ## Request URL ```http theme={null} POST https://app.tatango.com/api/v2/lists/{ID}/subscribers ``` # Adding Multiple Tags to Multiple Subscribers Source: https://developers.momogood.com/messaging/v2-api-reference/subscribers/adding-multiple-tags-to-multiple-subscribers POST /api/v2/lists/{ID}/bulk_taggings This endpoint applies multiple tags to multiple subscribers. Other uses You can also use this endpoint to mass remove tags from subscribers. For example if replace\_tags is true and your tags list is empty it will remove all tags from your numbers list ## Request URL ```http theme={null} POST https://app.tatango.com/api/v2/lists/{ID}/bulk_taggings ``` # Deleting tags from a Subscriber Source: https://developers.momogood.com/messaging/v2-api-reference/subscribers/deleting-tags-from-a-subscriber DELETE /api/v2/lists/{ID}/subscribers/{PHONE_NUMBER}/tags This endpoint deletes multiple tags from a subscriber. This endpoint allows you to remove multiple tags from a subscriber in a single request. Tags that don't exist on the subscriber will be reported in the response but won't cause the request to fail. ## Request URL ```http theme={null} DELETE https://app.tatango.com/api/v2/lists/{ID}/subscribers/{PHONE_NUMBER}/tags ``` # Get a List of Subscribed Phone Numbers Source: https://developers.momogood.com/messaging/v2-api-reference/subscribers/get-list-of-subscribed-phones GET /api/v2/lists/{ID}/subscribers This endpoint gets a list of subscribed phone numbers for the requested list. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists/{ID}/subscribers ``` # Get a List of Unsubscribed Phone Numbers Source: https://developers.momogood.com/messaging/v2-api-reference/subscribers/get-list-of-unsubscribed-phones GET /api/v2/lists/{ID}/subscribers/unsubscribed This endpoint gets a list of unsubscribed phone numbers. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists/{ID}/subscribers/unsubscribed ``` # Getting a Subscriber Source: https://developers.momogood.com/messaging/v2-api-reference/subscribers/getting-a-subscriber GET /api/v2/lists/{ID}/subscribers/{SUBSCRIBER_ID} This endpoint returns information about a current subscriber. ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists/{ID}/subscribers/{SUBSCRIBER_ID} ``` # Unsubscribing a Subscriber Source: https://developers.momogood.com/messaging/v2-api-reference/subscribers/unsubscribing-a-subscriber DELETE /api/v2/lists/{ID}/subscribers/{SUBSCRIBER_ID} This endpoint unsubscribes a subscriber. This endpoint removes a subscriber from a list by unsubscribing them. The subscriber will no longer receive messages from this specific list. ## Request URL ```http theme={null} DELETE https://app.tatango.com/api/v2/lists/{ID}/subscribers/{SUBSCRIBER_ID} ``` # Updating a Subscriber Source: https://developers.momogood.com/messaging/v2-api-reference/subscribers/updating-a-subscriber PUT /api/v2/lists/{ID}/subscribers/{SUBSCRIBER_ID} This endpoint updates a subscriber. ## Request URL ```http theme={null} PUT https://app.tatango.com/api/v2/lists/{ID}/subscribers/{SUBSCRIBER_ID} ``` ### FAQs **If I add tags to an existing subscriber, does that add the tags to existing, or replace existing?** * The tags are added to any tags already applied, not replaced. **Can I update custom subscriber data for a subscriber?** * Yes, the paramaters are listed below. # Deleting a Tag From All Subscribers Source: https://developers.momogood.com/messaging/v2-api-reference/tags/deleting-tag-from-all-subscribers DELETE /api/v2/lists/{ID}/tags This endpoint deletes tags from all subscribers with the tag. After the endpoint is called, please allow up to 10 minutes for the tags provided to be removed from all subscribers. ## Request URL ```http theme={null} DELETE https://app.tatango.com/api/v2/lists/{ID}/tags ``` # Send Transactional MMS Message Source: https://developers.momogood.com/messaging/v2-api-reference/transactional-messages/send-transactional-mms POST /api/v2/transactional_messages This endpoint sends a Transactional MMS Message. Transactional MMS Messages are limited to 5000 characters. ## Request URL ```http theme={null} POST https://app.tatango.com/api/v2/transactional_messages ``` # Send Transactional SMS Message Source: https://developers.momogood.com/messaging/v2-api-reference/transactional-messages/send-transactional-sms POST /api/v2/transactional_messages This endpoint sends a Transactional SMS Message. Transactional SMS Messages are limited to 160 characters. Messages sent with more than 160 characters will be rejected with a 422 response and an error message stating that the content is too long. ## Request URL ```http theme={null} POST https://app.tatango.com/api/v2/transactional_messages ``` # Creating a New Webhook for a List Source: https://developers.momogood.com/messaging/v2-api-reference/webhooks/creating-new-webhook-for-list POST /api/v2/lists/{ID}/webhooks This endpoint creates a webhook for a list ## Request URL ```http theme={null} POST https://app.tatango.com/api/v2/lists/{ID}/webhooks ``` # Destroying a Webhook Source: https://developers.momogood.com/messaging/v2-api-reference/webhooks/destroying-webhook DELETE /api/v2/lists/{ID}/webhooks/{WEBHOOK_ID} This endpoint destroys a webhook ## Request URL ```http theme={null} DELETE https://app.tatango.com/api/v2/lists/{ID}/webhooks/{WEBHOOK_ID} ``` # Listing Webhooks Source: https://developers.momogood.com/messaging/v2-api-reference/webhooks/listing-webhooks GET /api/v2/lists/{ID}/webhooks This endpoint lists webhooks ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists/{ID}/webhooks/ ``` # Showing a Webhook Source: https://developers.momogood.com/messaging/v2-api-reference/webhooks/showing-webhook GET /api/v2/lists/{ID}/webhooks/{WEBHOOK_ID} This endpoint shows a webhook ## Request URL ```http theme={null} GET https://app.tatango.com/api/v2/lists/{ID}/webhooks/{WEBHOOK_ID} ``` # Updating a Webhook Source: https://developers.momogood.com/messaging/v2-api-reference/webhooks/updating-webhook PUT /api/v2/lists/{ID}/webhooks/{WEBHOOK_ID} This endpoint updates a webhook ## Request URL ```http theme={null} PUT https://app.tatango.com/api/v2/lists/{ID}/webhooks/{WEBHOOK_ID} ``` # Webhook Events Source: https://developers.momogood.com/messaging/v2-api-reference/webhooks/webhook-event-info Callback URLs configured as a webhook in momoGood Messaging are retried 10 times when not reachable. After the 10th time, the system makes no further attempts to reach the callback URL. ## Webhook Events The momoGood Messaging webhooks system (formerly Tatango webhooks) allows you to subscribe to real-time notifications when something important happens in your account. The table below lists the event types currently available. | Webhook Event | Description | | ------------------ | ---------------------------------------------------------------- | | Subscribes | Occurs when a new number has subscribed to your list | | Unsubscribes | Occurs when a subscriber unsubscribes from your list | | Message Sent | Occurs when a broadcast message is sent | | Reply Received | Occurs when a reply to a message from your shortcode is received | | Subscriber Cleaned | Occurs when a subscriber is cleaned from your list | Each webhook event has a JSON payload whose schema is documented in the sections below. ### Subscribe Event | Property | Type | Description | | ------------------------- | ------- | -------------------------------------------- | | `type` | string | Always `"subscribe"` | | `timestamp` | string | ISO 8601 timestamp of the event | | `account_id` | integer | momoGood account identifier | | `campaign_id` | integer | List identifier | | `opt_id` | integer | Unique identifier for the opt-in event | | `phone_number` | string | Subscriber's phone number | | `carrier_id` | integer | Carrier identifier | | `carrier_name` | string | Name of the carrier | | `first_name` | string | Subscriber's first name | | `last_name` | string | Subscriber's last name | | `email_address` | string | Subscriber's email address | | `gender` | string | Subscriber's gender | | `zip_code` | string | Subscriber's ZIP code | | `birthdate` | string | Subscriber's birth date (MM/DD/YYYY) | | `birthday` | string | Subscriber's birthday (MM/DD) | | `tag_list` | array | Array of tags associated with the subscriber | | `first_opt_in_timestamp` | string | ISO 8601 timestamp of first opt-in | | `last_opt_in_method` | string | Method used for the opt-in | | `last_opt_in_keyword` | string | Keyword used for opt-in (if applicable) | | `total_messages_received` | integer | Total messages received by subscriber | ### Unsubscribe Event | Property | Type | Description | | ------------------------- | ------- | -------------------------------------------- | | `type` | string | Always `"unsubscribe"` | | `timestamp` | string | ISO 8601 timestamp of the event | | `unsubscribe_date` | string | ISO 8601 timestamp of unsubscribe action | | `account_id` | integer | momoGood account identifier | | `campaign_id` | integer | List identifier | | `opt_id` | integer | Unique identifier for the opt event | | `phone_number` | string | Subscriber's phone number | | `carrier_id` | integer | Carrier identifier | | `carrier_name` | string | Name of the carrier | | `first_name` | string | Subscriber's first name | | `last_name` | string | Subscriber's last name | | `email_address` | string | Subscriber's email address | | `gender` | string | Subscriber's gender | | `zip_code` | string | Subscriber's ZIP code | | `birthdate` | string | Subscriber's birth date | | `birthday` | string | Subscriber's birthday | | `tag_list` | array | Array of tags associated with the subscriber | | `first_opt_in_timestamp` | string | ISO 8601 timestamp of first opt-in | | `last_opt_in_method` | string | Last method used for opt-in | | `last_opt_in_keyword` | string | Last keyword used for opt-in | | `total_messages_received` | integer | Total messages received by subscriber | ### Message Sent Event | Property | Type | Description | | ------------------- | ------- | ---------------------------------------------------- | | `type` | string | Always `"message_sent"` | | `timestamp` | string | ISO 8601 timestamp of the event | | `account_id` | integer | momoGood account identifier | | `campaign_id` | integer | List identifier | | `message_id` | integer | Unique identifier for the message | | `message_name` | string | Name of the message | | `sent_timestamp` | string | ISO 8601 timestamp when message was sent | | `is_mms` | boolean | Whether the message is MMS (`true`) or SMS (`false`) | | `content` | string | Message content | | `recipient_count` | string | Number of intended recipients | | `success_count` | integer | Number of successful deliveries | | `bounce_count` | integer | Number of bounced messages | | `clean_count` | integer | Number of cleaned subscribers | | `unsubscribe_count` | integer | Number of unsubscribes from this message | | `send_cost` | number | Cost of sending the message | ### Reply Received Event | Property | Type | Description | | ------------------------ | ------- | -------------------------------------------- | | `type` | string | Always `"campaign_response"` | | `timestamp` | string | ISO 8601 timestamp of the event | | `account_id` | integer | momoGood account identifier | | `campaign_id` | integer | List identifier | | `message_id` | integer | ID of the message being replied to | | `sent_timestamp` | string | ISO 8601 timestamp of original message | | `content` | string | Content of the original message | | `response_timestamp` | string | ISO 8601 timestamp of the reply | | `reply_content` | string | Content of the subscriber's reply | | `opt_id` | integer | Unique identifier for the opt record | | `phone_number` | string | Subscriber's phone number | | `carrier_id` | integer | Carrier identifier | | `carrier_name` | string | Name of the carrier | | `first_name` | string | Subscriber's first name | | `last_name` | string | Subscriber's last name | | `email_address` | string | Subscriber's email address | | `gender` | string | Subscriber's gender | | `zip_code` | string | Subscriber's ZIP code | | `birthdate` | string | Subscriber's birth date | | `birthday` | string | Subscriber's birthday | | `tag_list` | array | Array of tags associated with the subscriber | | `first_opt_in_timestamp` | string | ISO 8601 timestamp of first opt-in | | `last_opt_in_method` | string | Method used for opt-in | | `last_opt_in_keyword` | string | Keyword used for opt-in | | `is_mms` | boolean | Whether the reply is MMS or SMS | | `attachment_urls` | array | Array of attachment URLs for MMS replies | ### Subscriber Cleaned Event | Property | Type | Description | | ----------------- | ------- | ---------------------------------------------- | | `type` | string | Always `"cleaned"` | | `timestamp` | string | ISO 8601 timestamp of the event | | `account_id` | integer | momoGood account identifier | | `campaign_id` | integer | List identifier | | `subscriber_id` | integer | Unique identifier for the subscriber | | `phone_number` | string | Subscriber's phone number | | `cleaned_at` | string | ISO 8601 timestamp when subscriber was cleaned | | `clean_reason` | string | Reason for the clean action | | `last_message_id` | integer | ID of the last message sent to subscriber |