{"id":19233716,"url":"https://github.com/brightdigit/spinetail","last_synced_at":"2025-07-24T20:09:25.666Z","repository":{"id":37968309,"uuid":"394643327","full_name":"brightdigit/Spinetail","owner":"brightdigit","description":"Swift package for interfacing with your Mailchimp account, audiences, campaigns, and more.","archived":false,"fork":false,"pushed_at":"2024-12-02T16:21:39.000Z","size":13836,"stargazers_count":8,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"v2.0.0","last_synced_at":"2025-04-13T04:05:19.262Z","etag":null,"topics":["ios","macos","mailchimp","mailchimp-api","mailchimp-api-v3","swift","vapor","watchos"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brightdigit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-10T12:21:26.000Z","updated_at":"2023-05-24T13:16:48.000Z","dependencies_parsed_at":"2024-11-09T16:11:54.966Z","dependency_job_id":null,"html_url":"https://github.com/brightdigit/Spinetail","commit_stats":{"total_commits":156,"total_committers":15,"mean_commits":10.4,"dds":0.5064102564102564,"last_synced_commit":"d7fab1c75de91dc264243257d498eae5af788ed8"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightdigit%2FSpinetail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightdigit%2FSpinetail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightdigit%2FSpinetail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightdigit%2FSpinetail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brightdigit","download_url":"https://codeload.github.com/brightdigit/Spinetail/tar.gz/refs/heads/v2.0.0","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249996256,"owners_count":21358097,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ios","macos","mailchimp","mailchimp-api","mailchimp-api-v3","swift","vapor","watchos"],"created_at":"2024-11-09T16:11:37.626Z","updated_at":"2025-04-21T04:33:24.924Z","avatar_url":"https://github.com/brightdigit.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\t\u003cimg alt=\"Spinetail\" title=\"Spinetail\" src=\"Assets/logo.svg\" height=\"200\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003e Spinetail \u003c/h1\u003e\n\nA Swift package for interfacing with your Mailchimp account, audiences, campaigns, and more. \n\n[![SwiftPM](https://img.shields.io/badge/SPM-Linux%20%7C%20iOS%20%7C%20macOS%20%7C%20watchOS%20%7C%20tvOS-success?logo=swift)](https://swift.org)\n[![Twitter](https://img.shields.io/badge/twitter-@brightdigit-blue.svg?style=flat)](http://twitter.com/brightdigit)\n![GitHub](https://img.shields.io/github/license/brightdigit/Spinetail)\n![GitHub issues](https://img.shields.io/github/issues/brightdigit/Spinetail)\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/brightdigit/Spinetail/Spinetail?label=Actions\u0026logo=github)\n[![Bitrise](https://img.shields.io/bitrise/b2595eab70c25d1b?logo=bitrise\u0026?label=bitrise\u0026token=rHUhEUFkU2RUL-KGmrKX1Q)](https://app.bitrise.io/app/b2595eab70c25d1b)\n\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fbrightdigit%2FSpinetail%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/brightdigit/Spinetail)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fbrightdigit%2FSpinetail%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/brightdigit/Spinetail)\n\n![Demonstration of Spinetail](Assets/SpinetailDemo.gif)\n\n\u003c!--ts--\u003e\n# Table of Contents\n\n* [🎬 Introduction](#-introduction)\n   * [What's a \u003cem\u003eSpinetail\u003c/em\u003e?](#whats-a-spinetail)\n   * [How to create and send an email campaign](#how-to-create-and-send-an-email-campaign)\n* [🎁 Features](#-features)\n* [🏗 Installation](#-installation)\n   * [Setting Up Your Mailchimp Client with Prch](#setting-up-your-mailchimp-client-with-prch)\n* [💪 Usage](#-usage)\n   * [🕊 _Prch_ Basics](#-prch-basics)\n\t  * [Closure-based Completion](#closure-based-completion)\n\t  * [Async/Await](#asyncawait)\n\t  * [Synchronous](#synchronous)\n   * [👩 Audience List Members](#-audience-list-members)\n\t  * [Getting an Audience List Member](#getting-an-audience-list-member)\n\t  * [Adding new Audience List Members](#adding-new-audience-list-members)\n\t  * [Updating Existing Audience List Members](#updating-existing-audience-list-members)\n\t  * [Putting it together in Vapor](#putting-it-together-in-vapor)\n   * [📩 Templates and Campaigns](#-templates-and-campaigns)\n\t  * [Pulling List of Campaigns](#pulling-list-of-campaigns)\n\t  * [Get Newsletter Content](#get-newsletter-content)\n\t  * [Creating a Template](#creating-a-template)\n\t  * [Send an Campaign Email to Our Audience List](#send-an-campaign-email-to-our-audience-list)\n* [📞 Requests](#-requests)\n   * [😁 Fully Supported](#-fully-supported)\n\t  * [Campaigns](#campaigns)\n\t  * [Lists](#lists)\n\t  * [Templates](#templates)\n   * [😊 Testing Pending](#testing-pending)\n\t  * [Template Folders](#template-folders)\n\t  * [Search Campaigns](#search-campaigns)\n\t  * [Search Members](#search-members)\n\t  * [Reports](#reports)\n\t  * [Root](#root)\n   * [😊 Pending Next Support](#-pending-next-support)\n\t  * [File Manager](#file-manager)\n\t  * [Batches](#batches)\n\t  * [Automations](#automations)\n   * [😌 Remaining Requests](#-remaining-requests)\n\t  * [Activity Feed](#activity-feed)\n\t  * [Authorized Apps](#authorized-apps)\n\t  * [Connected Sites](#connected-sites)\n\t  * [Conversations](#conversations)\n\t  * [Customer Journeys](#customer-journeys)\n\t  * [Ecommerce Stores](#ecommerce-stores)\n\t  * [Facebook Ads](#facebook-ads)\n\t  * [Landing Pages](#landing-pages)\n\t  * [Verified Domains](#verified-domains)\n* [🙏 Acknowledgments](#-acknowledgments)\n* [📜 License](#-license)\n\n\u003c!--te--\u003e\n\n# 🎬 Introduction\n\n**Spinetail** is a Swift package for interfacing with your Mailchimp account, audiences, campaigns, and more. \n\nBuilt on top of the code generated by [Swaggen by Yonas Kolb](https://github.com/yonaskolb/SwagGen) from [Mailchimp's OpenAPI Spec](https://github.com/mailchimp/mailchimp-client-lib-codegen) and optimized.\n\n## What's a _Spinetail_?\n\nA [Spinetail](https://en.wikipedia.org/wiki/Mottled_spinetail) is a type of Swift bird which shares it's habitat with chimps (such as the chimp in Mail\u003cem\u003echimp\u003c/em\u003e).\n\n## How to create and send an email campaign\n\n```swift\nlet listID : String = \"[Your List ID]\"\nlet mailchimpAPI = try Mailchimp.API(\n  apiKey: \"[ Your API Key : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us00 ]\"\n)\nlet client = Client(api: mailchimpAPI, session: URLSession.shared)\n\n// create the campaign template\nlet templateRequest = Templates.PostTemplates.Request(\n  body: .init(html: html, name: name)\n)\nlet template = try await self.request(templateRequest)\n\n// get the templateID\nguard let templateID = template.id else { \n  return\n}\n\n// setup the email\nlet settings: Campaigns.PostCampaigns.Request.Body.Settings = .init(\n  fromName: \"Leo\", \n  replyTo: \"leo@brightdigit.com\", \n  subjectLine: \"Hello World - Test Email\", \n  templateId: templateID\n)\n\n// setup the campaign\nlet body: Campaigns.PostCampaigns.Request.Body = .init(\n  type: .regular, \n  contentType: .template, \n  recipients: .init(listId: listID), \n  settings: settings\n)\n\nlet request = Campaigns.PostCampaigns.Request(body: body)\ntry await client.request(request)\n```\n\n# 🎁 Features \n\nHere's what's currently implemented with this library:\n\n- [x] Pulling Your Current List of Campaigns\n- [x] Send Email Campaigns to Your Lists \n- [x] Get Your Audience List\n- [x] Add to Your Audience List\n- [x] Updating Subscribers Tags and Interests\n\n... and more\n\n# 🏗 Installation\n\nTo integrate **Spinetail** into your project using SPM, specify it in your Package.swift file:\n\n```swift    \nlet package = Package(\n  ...\n  dependencies: [\n\t.package(url: \"https://github.com/brightdigit/Spinetail\", from: \"0.2.0\")\n  ],\n  targets: [\n\t  .target(\n\t\t  name: \"YourTarget\",\n\t\t  dependencies: [\"Spinetail\", ...]),\n\t  ...\n  ]\n)\n```\n\nSpinetail uses `URLSession` for network communication via [Prch](https://github.com/brightdigit/Prch).\n\nHowever if you are building a server-side application in Swift and wish to take advantage of SwiftNIO, then you'll want import [PrchNIO](https://github.com/brightdigit/PrchNIO) package as well:\n\n```swift    \nlet package = Package(\n  ...\n  dependencies: [\n\t.package(url: \"https://github.com/brightdigit/Spinetail\", from: \"0.2.0\"),\n\t.package(url: \"https://github.com/brightdigit/PrchNIO\", from: \"0.2.0\")\n  ],\n  targets: [\n\t  .target(\n\t\t  name: \"YourTarget\",\n\t\t  dependencies: [\"Spinetail\", \"PrchNIO\", ...]),\n\t  ...\n  ]\n)\n```\n\n[PrchNIO](https://github.com/brightdigit/PrchNIO) adds support for `EventLoopFuture` and using the networking infrastructure already supplied by SwiftNIO.\n\nIf you are using [Vapor](https://vapor.codes), then you may also want to consider using [SpinetailVapor](https://github.com/brightdigit/SpinetailVapor) package:\n\n```swift    \nlet package = Package(\n  ...\n  dependencies: [\n\t.package(url: \"https://github.com/brightdigit/Spinetail\", from: \"0.2.0\"),\n\t.package(url: \"https://github.com/brightdigit/SpinetailVapor\", from: \"0.2.0\")\n  ],\n  targets: [\n\t  .target(\n\t\t  name: \"YourTarget\",\n\t\t  dependencies: [\"Spinetail\", \"SpinetailVapor\", ...]),\n\t  ...\n  ]\n)\n```\n\nThe [SpinetailVapor](https://github.com/brightdigit/SpinetailVapor) package adds helper properties and methods to help with setting up and accessing the `Prch.Client`.\n\n## Setting Up Your Mailchimp Client with Prch\n\nIn order to get started with the Mailchimp API, [make sure you have created an API key](https://mailchimp.com/developer/marketing/guides/quick-start/#generate-your-api-key). Typically the API key looks something like this:\n\n```\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us00\n```\n\nOnce you have that, decide what you'll be using for your session depending on your platform:\n\n* `URLSession` - iOS, tvOS, watchOS, macOS _from [Prch](https://github.com/brightdigit/Prch)_\n* `AsyncHTTPClient` - Linux/Server _from [PrchNIO](https://github.com/brightdigit/PrchNIO)_\n* `Vapor.Client` - Vapor _from [PrchVapor](https://github.com/brightdigit/PrchVapor)_\n\nHere's an example for setting up a client for Mailchimp on a standard Apple platform app:\n \n```swift\nlet api = Mailchimp,API(apiKey: \"\")\nlet client = Client(api: api, session: URLSession.shared)\n```\n\nIf you are using **Vapor** then you'll want to configure your client inside your application configuration:\n\n```swift\napp.mailchimp.configure(withAPIKey: \"\")\n```\n\n... then you'll have access to it throughout your application and in your requests:\n\n```swift\nrequest.mailchimp.client.request(...)\napplication.mailchimp.client.request(...)\n```\n\nNow that we have setup the client, we'll be using let's begin to access the Mailchimp API.\n\n# 💪 Usage \n\n## 🕊 _Prch_ Basics\n\nTo make a request via `Prch`, we have three options using our `client`:\n\n* closure-based completion calls\n* async/await \n* synchronous calls\n\n#### Closure-based Completion\n\n```swift\nclient.request(request) { result in\n  switch result {\n  case let .success(member):\n\t  // Successful Retrieval\n\tbreak\n  case let .defaultResponse(statusCode, response):\n\t  // Non-2xx Response (ex. 404 member not found)\n\tbreak\n  case let .failure(error):\n\t  // Other Errors (ex. networking, decoding or encoding JSON...)\n\tbreak\n  }\n}\n```\n\n\n#### Async/Await \n\n```swift\ndo {\n  // Successful Retrieval\n  let member = try await client.request(request)\n} catch let error as ClientResponseResult\u003cLists.GetListsIdMembersId.Response\u003e.FailedResponseError {\n  // Non-2xx Response (ex. 404 member not found)\n} catch  {\n  // Other Errors (ex. networking, decoding or encoding JSON...)\n}\n```\n\n#### Synchronous\n\n```swift\ndo {\n  // Successful Retrieval\n  let member = try client.requestSync(request)\n} catch let error as ClientResponseResult\u003cLists.GetListsIdMembersId.Response\u003e.FailedResponseError {\n  // Non-2xx Response (ex. 404 member not found)\n} catch  {\n  // Other Errors (ex. networking, decoding or encoding JSON...)\n}\n```\n\nIn each case there are possible results:\n\n* The call was successful\n* The call failed but the response was valid such as a 4xx status code\n* The call failed due to an internal error (ex. decoding, encoding, networking, etc...)\n\nLet's start with an example using audience member lists.\n\n## 👩 Audience List Members\n\n### Getting an Audience List Member\n\nAccording to [the documentation for the Mailchimp API](https://mailchimp.com/developer/marketing/api/list-members/get-member-info/), we can get a member of our audience list based on their _subscriber_hash_.\nThis is described as:\n\n\u003e The MD5 hash of the lowercase version of the list member's email address. This endpoint also accepts a list member's email address or contact_id.\n\nThe means we can use:\n* MD5 hash of the lowercase version of the list member's email address _but also_\n* email address or\n* `contact_id`\n\nIn our case, we'll be using an email address to see if we have someone subscribed. \nAdditionally we need our audience's `listID` which is found on the audience settings page.\n\n![ListID at the Mailchimp Admin Page](Assets/Mailchimp-listID.png)\n\nWith that email address, we can create a `Request`:\n\n```swift\nimport Spinetail \n\nlet api = Mailchimp.API(apiKey: \"\")\nlet client = Client(api: api, session: URLSession.shared)\nlet request = Lists.GetListsIdMembersId.Request(listId: listId, subscriberHash: emailAddress)\n```\n\nAs previously noted there are three ways to execute a call. In this case, let's use the synchronous call:\n\n```swift\ndo {\n  // Successful Retrieval\n  let member = try client.requestSync(request)\n} catch let error as ClientResponseResult\u003cLists.GetListsIdMembersId.Response\u003e.FailedResponseError {\n  // Non-2xx Response (ex. 404 member not found)\n} catch  {\n  // Other Errors (ex. networking, decoding or encoding JSON...)\n}\n```\n\nThis is a good example of where we'd want to handle a `404`. If the member is found, we may need to just update them, otherwise we want go ahead and add that subscriber.\n\n### Adding new Audience List Members\n\nTo [add a new audience member](https://mailchimp.com/developer/marketing/api/list-members/add-member-to-list/) we need to create a `Lists.PostListsIdMembers.Request`:\n\n```swift\nlet request = Lists.PostListsIdMembers.Request(\n  listId: listID, \n  body: .init(\n    emailAddress: emailAddress, \n\tstatus: .subscribed, \n\ttimestampOpt: .init(), \n\ttimestampSignup: .init()\n  )\n)\n```\n\nNow that we have a request let's use the completion handler call for adding a new member:\n\n```swift\nclient.request(request) { result in\n  switch result {\n  case let .success(newMember):\n\t  // Successful Adding\n\tbreak\n  case let .defaultResponse(statusCode, response):\n\t  // Non-2xx Response\n\tbreak\n  case let .failure(error):\n\t  // Other Errors (ex. networking, decoding or encoding JSON...)\n\tbreak\n  }\n}\n```\n\n### Updating Existing Audience List Members\n\nLet's say our attempt to find an existing subscriber member succeeds but we need to [update the member's interests](https://mailchimp.com/developer/marketing/api/list-members/update-list-member/). \nWe can get `subscriberHash` from our found member and the [`interestID` can be queried](https://mailchimp.com/developer/marketing/api/interests/list-interests-in-category/). \n\n```swift\n// get the subscriber hash id\nlet subscriberHash = member.id\nlet patch = Lists.PatchListsIdMembersId.Request(\n  body: .init(\n    emailAddress: emailAddress,\n\temailType: nil, \n\tinterests: [interestID: true] \n  ), \n  options: .init(\n    listId: Self.listID, \n\tsubscriberHash: subscriberHash\n  )\n)\n```\n\n### Putting it together in Vapor\n\nHere's an example in [Vapor](https://vapor.codes) using [Model Middleware provided by Fluent](https://docs.vapor.codes/4.0/fluent/model/#lifecycle):\n\n```swift\nimport Fluent\nimport Prch\nimport PrchVapor\nimport Spinetail\nimport Vapor\n\nstruct MailchimpMiddleware: ModelMiddleware {\n  // our client created during server initialization\n  let client: Prch.Client\u003cPrchVapor.SessionClient, Spinetail.Mailchimp.API\u003e\n  \n  // the list id\n  let listID: String\n  \n  // the interest id \n  let interestID : String\n\n  func upsertSubscriptionForUser(\n    _ user: User, \n    withEventLoop eventLoop: EventLoop\n  ) -\u003e EventLoopFuture\u003cVoid\u003e {\n\tlet memberRequest = Lists.GetListsIdMembersId.Request(listId: listID, subscriberHash: user.email)\n\t// find the subscription member\n\treturn client.request(memberRequest).flatMapThrowing { response -\u003e in\n\t  switch response {\n\t  case .defaultResponse(statusCode: 404, _):\n\t\treturn nil\n\t  case let .success(member):\n\t\treturn member\n\t  default:\n\t\tthrow ClientError.invalidResponse\n\t  }\n\n\t}.flatMap { member in\n\t  // if the subscriber already exists and has the interest id, don't do anything\n\t  if member?.interests?[self.interestID] == true {\n\t\treturn eventLoop.future()\n\t  // if the subscriber already exists but doesn't have the interest id\n\t  } else if let subscriberHash = member?.id {\n\t  \t// update the subscriber\n\t\tlet patch = Lists.PatchListsIdMembersId.Request(body: \n\t\t  .init(\n\t\t    emailAddress: user.email, \n\t\t    emailType: nil, \n\t\t    interests: [self.interestID: true]), \n\t\t    options: Lists.PatchListsIdMembersId.Request.Options(\n\t\t      listId: self.listID, \n\t\t      subscriberHash: subscriberHash\n\t\t      )\n\t\t    )\n\t\t// transform to `Void` on success\n\t\treturn client.request(patch).success()\n\t  // if the subscriber doesn't already exists\n\t  } else {\n\t  \t// update the subscriber add them\n\t\tlet post = Lists.PostListsIdMembers.Request(\n\t\t  listId: self.listID, \n\t\t  body: .init(\n\t\t    emailAddress: user.email, \n\t\t    status: .subscribed, \n\t\t    interests: [self.interestID: true], \n\t\t    timestampOpt: .init(), \n\t\t    timestampSignup: .init()\n\t\t  )\n\t\t)\n\t\t// transform to `Void` on success\n\t\treturn client.request(post).success()\n\t  }\n\t}\n  }\n\n  // after adding the row to the db, add the user to our subscription list with the interest id\n  func create(model: User, on db: Database, next: AnyModelResponder) -\u003e EventLoopFuture\u003cVoid\u003e {\n\tnext.create(model, on: db).transform(to: model).flatMap { user in\n\t  self.upsertSubscriptionForUser(user, withEventLoop: db.eventLoop)\n\t}\n  }\n}\n```\n\nNow that we have an example dealing with managing members, let's look at how to get a list of campaigns and email our subscribers in Swift.\n\n## 📩 Templates and Campaigns\n\nWith newsletters there are [campaigns](https://mailchimp.com/developer/marketing/api/campaigns/) and [templates](https://mailchimp.com/developer/marketing/api/templates/). \n_Campaigns_ are how you send emails to your Mailchimp list. A _template_ is an HTML file used to create the layout and basic design for a campaign.\nBefore creating our own campaign and template, let's look at how to pull a list of campaigns.\n\n### Pulling List of Campaigns\n\nOn the BrightDigit web site, I want to link to each newsletter that's sent out. To do this you just need the `listID` again.\nWe'll be pulling up to 1000 sent campaigns sorted from last sent to first sent:\n\n```swift\nlet request = Campaigns.GetCampaigns.Request(\n  count: 1000, \n  status: .sent, \n  listId: listID, \n  sortField: .sendTime, \n  sortDir: .desc\n)\nlet response = try self.requestSync(request)\nlet campaigns = response.campaigns ?? []\n```\n\nTo get the content we to grab it based on each campaign's `campaignID`.\n\n### Get Newsletter Content\n\nBefore grabbing the content, we need to grab the `campaignID` from the campaign:\n\n```swift\nlet campaign : Campaigns.GetCampaigns.Response.Status200.Campaigns\nlet html: String\n\nguard let campaignID = campaign.id else {\n  return\n}\n\nhtml = try self.htmlFromCampaign(withID: campaignProperties.campaignID)\n```\n\n### Creating a Template\n\nTo actually send we need to create an [template](https://mailchimp.com/developer/marketing/api/templates/) using [the\n`POST` request](https://mailchimp.com/developer/marketing/api/templates/add-template/). Here's an example with async and await:\n\n```swift\nlet templateName = \"Example Email\"\nlet templateHTML = \"\u003cstrong\u003eHello World\u003c/strong\u003e\"\nlet templateRequest = Templates.PostTemplates.Request(body: .init(html: templateHTML, name: templateName))\nlet template = try await client.request(templateRequest)\n```\n\nLet's use the template to create a campaign and send it.\n\n\n### Send an Campaign Email to Our Audience List\n\n```swift\n// make sure to get the templateID\nguard let templateID = template.id else {\n  return\n}\n\n// set the email settings\nlet settings: Campaigns.PostCampaigns.Request.Body.Settings = .init(\n  fromName: \"Leo\", \n  replyTo: \"leo@brightdigit.com\", \n  subjectLine: \"Hello World - Test Email\", \n  templateId: templateID\n)\n// set the type and list you're sending to\nlet body: Campaigns.PostCampaigns.Request.Body = .init(\n  type: .regular, \n  contentType: .template, \n  recipients: .init(listId: listID), \n  settings: settings\n)\nlet request = Campaigns.PostCampaigns.Request(body: body)\nawait client.request(request)\n```\n\n# 📞 Requests\n\nList of APIs and the status of their support. \nIf you have any requests feel free to [submit an issue](https://github.com/brightdigit/Spinetail/issues/new/choose) or [pull-request](https://github.com/brightdigit/Spinetail/compare) to improve current support.\nFor more information on [the Mailchimp Marketing API, checkout their API documentation.](https://mailchimp.com/developer/marketing/)\n\n## 😁 Fully Supported\n\nDue to the limitation of existing 32-bit watchOS devices, the library need to exclude certain APIs to limit size. \nTherefore these sets of APIs are available on all operating systems and platforms including watchOS.\n\n### Campaigns\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| DeleteCampaignsId                                   |        |            | ✅       |\n| DeleteCampaignsIdFeedbackId                         |        |            | ✅       |\n| GetCampaigns                                        |        |            | ✅       |\n| GetCampaignsId                                      |        |            | ✅       |\n| GetCampaignsIdContent                               |        | ✅          | ✅       |\n| GetCampaignsIdFeedback                              |        |            | ✅       |\n| GetCampaignsIdFeedbackId                            |        |            | ✅       |\n| GetCampaignsIdSendChecklist                         |        |            | ✅       |\n| PatchCampaignsId                                    |        |            | ✅       |\n| PatchCampaignsIdFeedbackId                          |        |            | ✅       |\n| PostCampaigns                                       | ✅      | ✅          | ✅       |\n| PostCampaignsIdActionsCancelSend                    |        |            | ✅       |\n| PostCampaignsIdActionsCreateResend                  |        |            | ✅       |\n| PostCampaignsIdActionsPause                         |        |            | ✅       |\n| PostCampaignsIdActionsReplicate                     |        |            | ✅       |\n| PostCampaignsIdActionsResume                        |        |            | ✅       |\n| PostCampaignsIdActionsSchedule                      |        |            | ✅       |\n| PostCampaignsIdActionsSend                          |        |            | ✅       |\n| PostCampaignsIdActionsTest                          |        |            | ✅       |\n| PostCampaignsIdActionsUnschedule                    |        |            | ✅       |\n| PostCampaignsIdFeedback                             |        |            | ✅       |\n| PutCampaignsIdContent                               |        |            | ✅       |\n\n### Lists\n\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| DeleteListsId                                       |        |            | ✅       |\n| DeleteListsIdInterestCategoriesId                   |        |            | ✅       |\n| DeleteListsIdInterestCategoriesIdInterestsId        |        |            | ✅       |\n| DeleteListsIdMembersId                              |        |            | ✅       |\n| DeleteListsIdMembersIdNotesId                       |        |            | ✅       |\n| DeleteListsIdMergeFieldsId                          |        |            | ✅       |\n| DeleteListsIdSegmentsId                             |        |            | ✅       |\n| DeleteListsIdSegmentsIdMembersId                    |        |            | ✅       |\n| DeleteListsIdWebhooksId                             |        |            | ✅       |\n| GetListMemberTags                                   |        |            | ✅       |\n| GetLists                                            |        |            | ✅       |\n| GetListsId                                          |        |            | ✅       |\n| GetListsIdAbuseReports                              |        |            | ✅       |\n| GetListsIdAbuseReportsId                            |        |            | ✅       |\n| GetListsIdActivity                                  |        |            | ✅       |\n| GetListsIdClients                                   |        |            | ✅       |\n| GetListsIdGrowthHistory                             |        |            | ✅       |\n| GetListsIdGrowthHistoryId                           |        |            | ✅       |\n| GetListsIdInterestCategories                        |        |            | ✅       |\n| GetListsIdInterestCategoriesId                      |        |            | ✅       |\n| GetListsIdInterestCategoriesIdInterests             |        |            | ✅       |\n| GetListsIdInterestCategoriesIdInterestsId           |        |            | ✅       |\n| GetListsIdLocations                                 |        |            | ✅       |\n| GetListsIdMembers                                   |        |            | ✅       |\n| GetListsIdMembersId                                 | ✅      | ✅          | ✅       |\n| GetListsIdMembersIdActivity                         |        |            | ✅       |\n| GetListsIdMembersIdActivityFeed                     |        |            | ✅       |\n| GetListsIdMembersIdEvents                           |        |            | ✅       |\n| GetListsIdMembersIdGoals                            |        |            | ✅       |\n| GetListsIdMembersIdNotes                            |        |            | ✅       |\n| GetListsIdMembersIdNotesId                          |        |            | ✅       |\n| GetListsIdMergeFields                               |        |            | ✅       |\n| GetListsIdMergeFieldsId                             |        |            | ✅       |\n| GetListsIdSegmentsId                                |        |            | ✅       |\n| GetListsIdSegmentsIdMembers                         |        |            | ✅       |\n| GetListsIdSignupForms                               |        |            | ✅       |\n| GetListsIdWebhooks                                  |        |            | ✅       |\n| GetListsIdWebhooksId                                |        |            | ✅       |\n| PatchListsId                                        |        |            | ✅       |\n| PatchListsIdInterestCategoriesId                    |        |            | ✅       |\n| PatchListsIdInterestCategoriesIdInterestsId         |        |            | ✅       |\n| PatchListsIdMembersId                               | ✅      | ✅          | ✅       |\n| PatchListsIdMembersIdNotesId                        |        |            | ✅       |\n| PatchListsIdMergeFieldsId                           |        |            | ✅       |\n| PatchListsIdSegmentsId                              |        |            | ✅       |\n| PatchListsIdWebhooksId                              |        |            | ✅       |\n| PostListMemberEvents                                |        |            | ✅       |\n| PostListMemberTags                                  |        |            | ✅       |\n| PostLists                                           |        |            | ✅       |\n| PostListsId                                         |        |            | ✅       |\n| PostListsIdInterestCategories                       |        |            | ✅       |\n| PostListsIdInterestCategoriesIdInterests            |        |            | ✅       |\n| PostListsIdMembers                                  | ✅      | ✅          | ✅       |\n| PostListsIdMembersHashActionsDeletePermanent        |        |            | ✅       |\n| PostListsIdMembersIdNotes                           |        |            | ✅       |\n| PostListsIdMergeFields                              |        |            | ✅       |\n| PostListsIdSegments                                 |        |            | ✅       |\n| PostListsIdSegmentsId                               |        |            | ✅       |\n| PostListsIdSegmentsIdMembers                        |        |            | ✅       |\n| PostListsIdSignupForms                              |        |            | ✅       |\n| PostListsIdWebhooks                                 |        |            | ✅       |\n| PreviewASegment                                     |        |            | ✅       |\n| PutListsIdMembersId                                 |        |            | ✅       |\n| SearchTagsByName                                    |        |            | ✅       |\n\n### Templates\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| GetTemplates                                        |        |            | ✅       |\n| GetTemplatesId                                      |        |            | ✅       |\n| GetTemplatesIdDefaultContent                        |        |            | ✅       |\n| PatchTemplatesId                                    |        |            | ✅       |\n| PostTemplates                                       | ✅      | ✅          | ✅       |\n\n## Testing Pending\n\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| DeleteCampaignFoldersId                             |        |            | ✅      |\n| GetCampaignFolders                                  |        |            | ✅      |\n| GetCampaignFoldersId                                |        |            | ✅      |\n| PatchCampaignFoldersId                              |        |            | ✅      |\n| PostCampaignFolders                                 |        |            | ✅      |\n\n### Template Folders\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| DeleteTemplateFoldersId                             |        |            | ✅       |\n| GetTemplateFolders                                  |        |            | ✅       |\n| GetTemplateFoldersId                                |        |            | ✅       |\n| PatchTemplateFoldersId                              |        |            | ✅       |\n| PostTemplateFolders                                 |        |            | ✅       |\n| DeleteTemplatesId                                   |        |            | ✅       |\n\n### Search Campaigns\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| GetSearchCampaigns                                  |        |            | ✅       |\n\n### Search Members\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| GetSearchMembers                                    |        |            | ✅       |\n\n### Reports\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| GetReports                                          |        |            | ✅       |\n| GetReportsId                                        |        |            | ✅       |\n| GetReportsIdAbuseReportsId                          |        |            | ✅       |\n| GetReportsIdAbuseReportsIdId                        |        |            | ✅       |\n| GetReportsIdAdvice                                  |        |            | ✅       |\n| GetReportsIdClickDetails                            |        |            | ✅       |\n| GetReportsIdClickDetailsId                          |        |            | ✅       |\n| GetReportsIdClickDetailsIdMembers                   |        |            | ✅       |\n| GetReportsIdClickDetailsIdMembersId                 |        |            | ✅       |\n| GetReportsIdDomainPerformance                       |        |            | ✅       |\n| GetReportsIdEcommerceProductActivity                |        |            | ✅       |\n| GetReportsIdEepurl                                  |        |            | ✅       |\n| GetReportsIdEmailActivity                           |        |            | ✅       |\n| GetReportsIdEmailActivityId                         |        |            | ✅       |\n| GetReportsIdLocations                               |        |            | ✅       |\n| GetReportsIdOpenDetails                             |        |            | ✅       |\n| GetReportsIdOpenDetailsIdMembersId                  |        |            | ✅       |\n| GetReportsIdSentTo                                  |        |            | ✅       |\n| GetReportsIdSentToId                                |        |            | ✅       |\n| GetReportsIdSubReportsId                            |        |            | ✅       |\n| GetReportsIdUnsubscribed                            |        |            | ✅       |\n| GetReportsIdUnsubscribedId                          |        |            | ✅       |\n\n### Root\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| GetRoot                                             |        |            | ✅       |\n\n## 😊 Pending Next Support\n\nThese are the next set of API for which migrating to watchOS is desired as well as more robust testing and documentation.\nIf you have any requests feel free to [submit an issue](https://github.com/brightdigit/Spinetail/issues/new/choose) or [pull-request](https://github.com/brightdigit/Spinetail/compare) to improve current support.\n\n### File Manager\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| DeleteFileManagerFilesId                            |        |            |         |\n| DeleteFileManagerFoldersId                          |        |            |         |\n| GetFileManagerFiles                                 |        |            |         |\n| GetFileManagerFilesId                               |        |            |         |\n| GetFileManagerFolders                               |        |            |         |\n| GetFileManagerFoldersId                             |        |            |         |\n| PatchFileManagerFilesId                             |        |            |         |\n| PatchFileManagerFoldersId                           |        |            |         |\n| PostFileManagerFiles                                |        |            |         |\n| PostFileManagerFolders                              |        |            |         |\n\n### Batches\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| DeleteBatchesId                                     |        |            |         |\n| GetBatches                                          |        |            |         |\n| GetBatchesId                                        |        |            |         |\n| PostBatches                                         |        |            |         |\n| DeleteBatchWebhookId                                |        |            |         |\n| GetBatchWebhook                                     |        |            |         |\n| GetBatchWebhooks                                    |        |            |         |\n| PatchBatchWebhooks                                  |        |            |         |\n| PostBatchWebhooks                                   |        |            |         |\n\n### Automations\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| ArchiveAutomations                                  |        |            |         |\n| DeleteAutomationsIdEmailsId                         |        |            |         |\n| GetAutomations                                      |        |            |         |\n| GetAutomationsId                                    |        |            |         |\n| GetAutomationsIdEmails                              |        |            |         |\n| GetAutomationsIdEmailsId                            |        |            |         |\n| GetAutomationsIdEmailsIdQueue                       |        |            |         |\n| GetAutomationsIdEmailsIdQueueId                     |        |            |         |\n| GetAutomationsIdRemovedSubscribers                  |        |            |         |\n| GetAutomationsIdRemovedSubscribersId                |        |            |         |\n| PatchAutomationEmailWorkflowId                      |        |            |         |\n| PostAutomations                                     |        |            |         |\n| PostAutomationsIdActionsPauseAllEmails              |        |            |         |\n| PostAutomationsIdActionsStartAllEmails              |        |            |         |\n| PostAutomationsIdEmailsIdActionsPause               |        |            |         |\n| PostAutomationsIdEmailsIdActionsStart               |        |            |         |\n| PostAutomationsIdEmailsIdQueue                      |        |            |         |\n| PostAutomationsIdRemovedSubscribers                 |        |            |         |\n\n## 😌 Remaining Requests\n\nThese are the least priority set of API for which migrating to watchOS as well as robust testing and documentation have been prioritized.\nIf you have any requests feel free to [submit an issue](https://github.com/brightdigit/Spinetail/issues/new/choose) or [pull-request](https://github.com/brightdigit/Spinetail/compare) to improve current support.\n\n\n### Activity Feed\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| GetActivityFeedChimpChatter                         |        |            |         |\n\n### Authorized Apps\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| GetAuthorizedApps                                   |        |            |         |\n| GetAuthorizedAppsId                                 |        |            |         |\n\n### Connected Sites\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| DeleteConnectedSitesId                              |        |            |         |\n| GetConnectedSites                                   |        |            |         |\n| GetConnectedSitesId                                 |        |            |         |\n| PostConnectedSites                                  |        |            |         |\n| PostConnectedSitesIdActionsVerifyScriptInstallation |        |            |         |\n\n### Conversations\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| GetConversations                                    |        |            |         |\n| GetConversationsId                                  |        |            |         |\n| GetConversationsIdMessages                          |        |            |         |\n| GetConversationsIdMessagesId                        |        |            |         |\n\n### Customer Journeys\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| PostCustomerJourneysJourneysIdStepsIdActionsTrigger |        |            |         |\n\n### Ecommerce Stores\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| DeleteEcommerceStoresId                             |        |            |         |\n| DeleteEcommerceStoresIdCartsId                      |        |            |         |\n| DeleteEcommerceStoresIdCartsLinesId                 |        |            |         |\n| DeleteEcommerceStoresIdCustomersId                  |        |            |         |\n| DeleteEcommerceStoresIdOrdersId                     |        |            |         |\n| DeleteEcommerceStoresIdOrdersIdLinesId              |        |            |         |\n| DeleteEcommerceStoresIdProductsId                   |        |            |         |\n| DeleteEcommerceStoresIdProductsIdImagesId           |        |            |         |\n| DeleteEcommerceStoresIdProductsIdVariantsId         |        |            |         |\n| DeleteEcommerceStoresIdPromocodesId                 |        |            |         |\n| DeleteEcommerceStoresIdPromorulesId                 |        |            |         |\n| GetEcommerceOrders                                  |        |            |         |\n| GetEcommerceStores                                  |        |            |         |\n| GetEcommerceStoresId                                |        |            |         |\n| GetEcommerceStoresIdCarts                           |        |            |         |\n| GetEcommerceStoresIdCartsId                         |        |            |         |\n| GetEcommerceStoresIdCartsIdLines                    |        |            |         |\n| GetEcommerceStoresIdCartsIdLinesId                  |        |            |         |\n| GetEcommerceStoresIdCustomers                       |        |            |         |\n| GetEcommerceStoresIdCustomersId                     |        |            |         |\n| GetEcommerceStoresIdOrders                          |        |            |         |\n| GetEcommerceStoresIdOrdersId                        |        |            |         |\n| GetEcommerceStoresIdOrdersIdLines                   |        |            |         |\n| GetEcommerceStoresIdOrdersIdLinesId                 |        |            |         |\n| GetEcommerceStoresIdProducts                        |        |            |         |\n| GetEcommerceStoresIdProductsId                      |        |            |         |\n| GetEcommerceStoresIdProductsIdImages                |        |            |         |\n| GetEcommerceStoresIdProductsIdImagesId              |        |            |         |\n| GetEcommerceStoresIdProductsIdVariants              |        |            |         |\n| GetEcommerceStoresIdProductsIdVariantsId            |        |            |         |\n| GetEcommerceStoresIdPromocodes                      |        |            |         |\n| GetEcommerceStoresIdPromocodesId                    |        |            |         |\n| GetEcommerceStoresIdPromorules                      |        |            |         |\n| GetEcommerceStoresIdPromorulesId                    |        |            |         |\n| PatchEcommerceStoresId                              |        |            |         |\n| PatchEcommerceStoresIdCartsId                       |        |            |         |\n| PatchEcommerceStoresIdCartsIdLinesId                |        |            |         |\n| PatchEcommerceStoresIdCustomersId                   |        |            |         |\n| PatchEcommerceStoresIdOrdersId                      |        |            |         |\n| PatchEcommerceStoresIdOrdersIdLinesId               |        |            |         |\n| PatchEcommerceStoresIdProductsId                    |        |            |         |\n| PatchEcommerceStoresIdProductsIdImagesId            |        |            |         |\n| PatchEcommerceStoresIdProductsIdVariantsId          |        |            |         |\n| PatchEcommerceStoresIdPromocodesId                  |        |            |         |\n| PatchEcommerceStoresIdPromorulesId                  |        |            |         |\n| PostEcommerceStores                                 |        |            |         |\n| PostEcommerceStoresIdCarts                          |        |            |         |\n| PostEcommerceStoresIdCartsIdLines                   |        |            |         |\n| PostEcommerceStoresIdCustomers                      |        |            |         |\n| PostEcommerceStoresIdOrders                         |        |            |         |\n| PostEcommerceStoresIdOrdersIdLines                  |        |            |         |\n| PostEcommerceStoresIdProducts                       |        |            |         |\n| PostEcommerceStoresIdProductsIdImages               |        |            |         |\n| PostEcommerceStoresIdProductsIdVariants             |        |            |         |\n| PostEcommerceStoresIdPromocodes                     |        |            |         |\n| PostEcommerceStoresIdPromorules                     |        |            |         |\n| PutEcommerceStoresIdCustomersId                     |        |            |         |\n| PutEcommerceStoresIdProductsIdVariantsId            |        |            |         |\n\n### Facebook Ads\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| GetAllFacebookAds                                   |        |            |         |\n| GetFacebookAdsId                                    |        |            |         |\n\n### Landing Pages\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| DeleteLandingPageId                                 |        |            |         |\n| GetAllLandingPages                                  |        |            |         |\n| GetLandingPageId                                    |        |            |         |\n| GetLandingPageIdContent                             |        |            |         |\n| PatchLandingPageId                                  |        |            |         |\n| PostAllLandingPages                                 |        |            |         |\n| PostLandingPageIdActionsPublish                     |        |            |         |\n| PostLandingPageIdActionsUnpublish                   |        |            |         |\n\n### Verified Domains\n\n| Request                                             | Tested | Documented | watchOS |\n| --------------------------------------------------- | ------ | ---------- | ------- |\n| CreateVerifiedDomain                                |        |            |         |\n| DeleteVerifiedDomain                                |        |            |         |\n| GetVerifiedDomain                                   |        |            |         |\n| GetVerifiedDomains                                  |        |            |         |\n| VerifyDomain                                        |        |\t\t   |         |\n\n# 🙏 Acknowledgments\n\nThanks to [Yonas Kolb](https://github.com/yonaskolb/swaggen) for his work on a variety of project but especially [Swaggen](https://github.com/yonaskolb).\n\n# 📜 License \n\nThis code is distributed under the MIT license. See the [LICENSE](LICENSE) file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrightdigit%2Fspinetail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrightdigit%2Fspinetail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrightdigit%2Fspinetail/lists"}