A Swift package for interfacing with your Mailchimp account, audiences, campaigns, and more.
- 🎬 Introduction
- 🎁 Features
- 🏗 Installation
- 💪 Usage
- 📞 Requests
- 🙏 Acknowledgments
- 📜 License
Spinetail is a Swift package for interfacing with your Mailchimp account, audiences, campaigns, and more.
Built on top of the code generated by Swaggen by Yonas Kolb from Mailchimp's OpenAPI Spec and optimized.
A Spinetail is a type of Swift bird which shares it's habitat with chimps (such as the chimp in Mailchimp).
let listID : String = "[Your List ID]"
let mailchimpAPI = try Mailchimp.API(
apiKey: "[ Your API Key : xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us00 ]"
)
let client = Client(api: mailchimpAPI, session: URLSession.shared)
// create the campaign template
let templateRequest = Templates.PostTemplates.Request(
body: .init(html: html, name: name)
)
let template = try await self.request(templateRequest)
// get the templateID
guard let templateID = template.id else {
return
}
// setup the email
let settings: Campaigns.PostCampaigns.Request.Body.Settings = .init(
fromName: "Leo",
replyTo: "[email protected]",
subjectLine: "Hello World - Test Email",
templateId: templateID
)
// setup the campaign
let body: Campaigns.PostCampaigns.Request.Body = .init(
type: .regular,
contentType: .template,
recipients: .init(listId: listID),
settings: settings
)
let request = Campaigns.PostCampaigns.Request(body: body)
try await client.request(request)
Here's what's currently implemented with this library:
- Pulling Your Current List of Campaigns
- Send Email Campaigns to Your Lists
- Get Your Audience List
- Add to Your Audience List
- Updating Subscribers Tags and Interests
... and more
To integrate Spinetail into your project using SPM, specify it in your Package.swift file:
let package = Package(
...
dependencies: [
.package(url: "https://github.com/brightdigit/Spinetail", from: "0.2.0")
],
targets: [
.target(
name: "YourTarget",
dependencies: ["Spinetail", ...]),
...
]
)
Spinetail uses URLSession
for network communication via Prch.
However if you are building a server-side application in Swift and wish to take advantage of SwiftNIO, then you'll want import PrchNIO package as well:
let package = Package(
...
dependencies: [
.package(url: "https://github.com/brightdigit/Spinetail", from: "0.2.0"),
.package(url: "https://github.com/brightdigit/PrchNIO", from: "0.2.0")
],
targets: [
.target(
name: "YourTarget",
dependencies: ["Spinetail", "PrchNIO", ...]),
...
]
)
PrchNIO adds support for EventLoopFuture
and using the networking infrastructure already supplied by SwiftNIO.
If you are using Vapor, then you may also want to consider using SpinetailVapor package:
let package = Package(
...
dependencies: [
.package(url: "https://github.com/brightdigit/Spinetail", from: "0.2.0"),
.package(url: "https://github.com/brightdigit/SpinetailVapor", from: "0.2.0")
],
targets: [
.target(
name: "YourTarget",
dependencies: ["Spinetail", "SpinetailVapor", ...]),
...
]
)
The SpinetailVapor package adds helper properties and methods to help with setting up and accessing the Prch.Client
.
In order to get started with the Mailchimp API, make sure you have created an API key. Typically the API key looks something like this:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-us00
Once you have that, decide what you'll be using for your session depending on your platform:
URLSession
- iOS, tvOS, watchOS, macOS from PrchAsyncHTTPClient
- Linux/Server from PrchNIOVapor.Client
- Vapor from PrchVapor
Here's an example for setting up a client for Mailchimp on a standard Apple platform app:
let api = Mailchimp,API(apiKey: "")
let client = Client(api: api, session: URLSession.shared)
If you are using Vapor then you'll want to configure your client inside your application configuration:
app.mailchimp.configure(withAPIKey: "")
... then you'll have access to it throughout your application and in your requests:
request.mailchimp.client.request(...)
application.mailchimp.client.request(...)
Now that we have setup the client, we'll be using let's begin to access the Mailchimp API.
To make a request via Prch
, we have three options using our client
:
- closure-based completion calls
- async/await
- synchronous calls
client.request(request) { result in
switch result {
case let .success(member):
// Successful Retrieval
break
case let .defaultResponse(statusCode, response):
// Non-2xx Response (ex. 404 member not found)
break
case let .failure(error):
// Other Errors (ex. networking, decoding or encoding JSON...)
break
}
}
do {
// Successful Retrieval
let member = try await client.request(request)
} catch let error as ClientResponseResult<Lists.GetListsIdMembersId.Response>.FailedResponseError {
// Non-2xx Response (ex. 404 member not found)
} catch {
// Other Errors (ex. networking, decoding or encoding JSON...)
}
do {
// Successful Retrieval
let member = try client.requestSync(request)
} catch let error as ClientResponseResult<Lists.GetListsIdMembersId.Response>.FailedResponseError {
// Non-2xx Response (ex. 404 member not found)
} catch {
// Other Errors (ex. networking, decoding or encoding JSON...)
}
In each case there are possible results:
- The call was successful
- The call failed but the response was valid such as a 4xx status code
- The call failed due to an internal error (ex. decoding, encoding, networking, etc...)
Let's start with an example using audience member lists.
According to the documentation for the Mailchimp API, we can get a member of our audience list based on their subscriber_hash. This is described as:
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.
The means we can use:
- MD5 hash of the lowercase version of the list member's email address but also
- email address or
contact_id
In our case, we'll be using an email address to see if we have someone subscribed.
Additionally we need our audience's listID
which is found on the audience settings page.
With that email address, we can create a Request
:
import Spinetail
let api = Mailchimp.API(apiKey: "")
let client = Client(api: api, session: URLSession.shared)
let request = Lists.GetListsIdMembersId.Request(listId: listId, subscriberHash: emailAddress)
As previously noted there are three ways to execute a call. In this case, let's use the synchronous call:
do {
// Successful Retrieval
let member = try client.requestSync(request)
} catch let error as ClientResponseResult<Lists.GetListsIdMembersId.Response>.FailedResponseError {
// Non-2xx Response (ex. 404 member not found)
} catch {
// Other Errors (ex. networking, decoding or encoding JSON...)
}
This 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.
To add a new audience member we need to create a Lists.PostListsIdMembers.Request
:
let request = Lists.PostListsIdMembers.Request(
listId: listID,
body: .init(
emailAddress: emailAddress,
status: .subscribed,
timestampOpt: .init(),
timestampSignup: .init()
)
)
Now that we have a request let's use the completion handler call for adding a new member:
client.request(request) { result in
switch result {
case let .success(newMember):
// Successful Adding
break
case let .defaultResponse(statusCode, response):
// Non-2xx Response
break
case let .failure(error):
// Other Errors (ex. networking, decoding or encoding JSON...)
break
}
}
Let's say our attempt to find an existing subscriber member succeeds but we need to update the member's interests.
We can get subscriberHash
from our found member and the interestID
can be queried.
// get the subscriber hash id
let subscriberHash = member.id
let patch = Lists.PatchListsIdMembersId.Request(
body: .init(
emailAddress: emailAddress,
emailType: nil,
interests: [interestID: true]
),
options: .init(
listId: Self.listID,
subscriberHash: subscriberHash
)
)
Here's an example in Vapor using Model Middleware provided by Fluent:
import Fluent
import Prch
import PrchVapor
import Spinetail
import Vapor
struct MailchimpMiddleware: ModelMiddleware {
// our client created during server initialization
let client: Prch.Client<PrchVapor.SessionClient, Spinetail.Mailchimp.API>
// the list id
let listID: String
// the interest id
let interestID : String
func upsertSubscriptionForUser(
_ user: User,
withEventLoop eventLoop: EventLoop
) -> EventLoopFuture<Void> {
let memberRequest = Lists.GetListsIdMembersId.Request(listId: listID, subscriberHash: user.email)
// find the subscription member
return client.request(memberRequest).flatMapThrowing { response -> in
switch response {
case .defaultResponse(statusCode: 404, _):
return nil
case let .success(member):
return member
default:
throw ClientError.invalidResponse
}
}.flatMap { member in
// if the subscriber already exists and has the interest id, don't do anything
if member?.interests?[self.interestID] == true {
return eventLoop.future()
// if the subscriber already exists but doesn't have the interest id
} else if let subscriberHash = member?.id {
// update the subscriber
let patch = Lists.PatchListsIdMembersId.Request(body:
.init(
emailAddress: user.email,
emailType: nil,
interests: [self.interestID: true]),
options: Lists.PatchListsIdMembersId.Request.Options(
listId: self.listID,
subscriberHash: subscriberHash
)
)
// transform to `Void` on success
return client.request(patch).success()
// if the subscriber doesn't already exists
} else {
// update the subscriber add them
let post = Lists.PostListsIdMembers.Request(
listId: self.listID,
body: .init(
emailAddress: user.email,
status: .subscribed,
interests: [self.interestID: true],
timestampOpt: .init(),
timestampSignup: .init()
)
)
// transform to `Void` on success
return client.request(post).success()
}
}
}
// after adding the row to the db, add the user to our subscription list with the interest id
func create(model: User, on db: Database, next: AnyModelResponder) -> EventLoopFuture<Void> {
next.create(model, on: db).transform(to: model).flatMap { user in
self.upsertSubscriptionForUser(user, withEventLoop: db.eventLoop)
}
}
}
Now 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.
With newsletters there are campaigns and templates. 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. Before creating our own campaign and template, let's look at how to pull a list of campaigns.
On the BrightDigit web site, I want to link to each newsletter that's sent out. To do this you just need the listID
again.
We'll be pulling up to 1000 sent campaigns sorted from last sent to first sent:
let request = Campaigns.GetCampaigns.Request(
count: 1000,
status: .sent,
listId: listID,
sortField: .sendTime,
sortDir: .desc
)
let response = try self.requestSync(request)
let campaigns = response.campaigns ?? []
To get the content we to grab it based on each campaign's campaignID
.
Before grabbing the content, we need to grab the campaignID
from the campaign:
let campaign : Campaigns.GetCampaigns.Response.Status200.Campaigns
let html: String
guard let campaignID = campaign.id else {
return
}
html = try self.htmlFromCampaign(withID: campaignProperties.campaignID)
To actually send we need to create an template using the
POST
request. Here's an example with async and await:
let templateName = "Example Email"
let templateHTML = "<strong>Hello World</strong>"
let templateRequest = Templates.PostTemplates.Request(body: .init(html: templateHTML, name: templateName))
let template = try await client.request(templateRequest)
Let's use the template to create a campaign and send it.
// make sure to get the templateID
guard let templateID = template.id else {
return
}
// set the email settings
let settings: Campaigns.PostCampaigns.Request.Body.Settings = .init(
fromName: "Leo",
replyTo: "[email protected]",
subjectLine: "Hello World - Test Email",
templateId: templateID
)
// set the type and list you're sending to
let body: Campaigns.PostCampaigns.Request.Body = .init(
type: .regular,
contentType: .template,
recipients: .init(listId: listID),
settings: settings
)
let request = Campaigns.PostCampaigns.Request(body: body)
await client.request(request)
List of APIs and the status of their support. If you have any requests feel free to submit an issue or pull-request to improve current support. For more information on the Mailchimp Marketing API, checkout their API documentation.
Due to the limitation of existing 32-bit watchOS devices, the library need to exclude certain APIs to limit size. Therefore these sets of APIs are available on all operating systems and platforms including watchOS.
Request | Tested | Documented | watchOS |
---|---|---|---|
DeleteCampaignsId | ✅ | ||
DeleteCampaignsIdFeedbackId | ✅ | ||
GetCampaigns | ✅ | ||
GetCampaignsId | ✅ | ||
GetCampaignsIdContent | ✅ | ✅ | |
GetCampaignsIdFeedback | ✅ | ||
GetCampaignsIdFeedbackId | ✅ | ||
GetCampaignsIdSendChecklist | ✅ | ||
PatchCampaignsId | ✅ | ||
PatchCampaignsIdFeedbackId | ✅ | ||
PostCampaigns | ✅ | ✅ | ✅ |
PostCampaignsIdActionsCancelSend | ✅ | ||
PostCampaignsIdActionsCreateResend | ✅ | ||
PostCampaignsIdActionsPause | ✅ | ||
PostCampaignsIdActionsReplicate | ✅ | ||
PostCampaignsIdActionsResume | ✅ | ||
PostCampaignsIdActionsSchedule | ✅ | ||
PostCampaignsIdActionsSend | ✅ | ||
PostCampaignsIdActionsTest | ✅ | ||
PostCampaignsIdActionsUnschedule | ✅ | ||
PostCampaignsIdFeedback | ✅ | ||
PutCampaignsIdContent | ✅ |
Request | Tested | Documented | watchOS |
---|---|---|---|
DeleteListsId | ✅ | ||
DeleteListsIdInterestCategoriesId | ✅ | ||
DeleteListsIdInterestCategoriesIdInterestsId | ✅ | ||
DeleteListsIdMembersId | ✅ | ||
DeleteListsIdMembersIdNotesId | ✅ | ||
DeleteListsIdMergeFieldsId | ✅ | ||
DeleteListsIdSegmentsId | ✅ | ||
DeleteListsIdSegmentsIdMembersId | ✅ | ||
DeleteListsIdWebhooksId | ✅ | ||
GetListMemberTags | ✅ | ||
GetLists | ✅ | ||
GetListsId | ✅ | ||
GetListsIdAbuseReports | ✅ | ||
GetListsIdAbuseReportsId | ✅ | ||
GetListsIdActivity | ✅ | ||
GetListsIdClients | ✅ | ||
GetListsIdGrowthHistory | ✅ | ||
GetListsIdGrowthHistoryId | ✅ | ||
GetListsIdInterestCategories | ✅ | ||
GetListsIdInterestCategoriesId | ✅ | ||
GetListsIdInterestCategoriesIdInterests | ✅ | ||
GetListsIdInterestCategoriesIdInterestsId | ✅ | ||
GetListsIdLocations | ✅ | ||
GetListsIdMembers | ✅ | ||
GetListsIdMembersId | ✅ | ✅ | ✅ |
GetListsIdMembersIdActivity | ✅ | ||
GetListsIdMembersIdActivityFeed | ✅ | ||
GetListsIdMembersIdEvents | ✅ | ||
GetListsIdMembersIdGoals | ✅ | ||
GetListsIdMembersIdNotes | ✅ | ||
GetListsIdMembersIdNotesId | ✅ | ||
GetListsIdMergeFields | ✅ | ||
GetListsIdMergeFieldsId | ✅ | ||
GetListsIdSegmentsId | ✅ | ||
GetListsIdSegmentsIdMembers | ✅ | ||
GetListsIdSignupForms | ✅ | ||
GetListsIdWebhooks | ✅ | ||
GetListsIdWebhooksId | ✅ | ||
PatchListsId | ✅ | ||
PatchListsIdInterestCategoriesId | ✅ | ||
PatchListsIdInterestCategoriesIdInterestsId | ✅ | ||
PatchListsIdMembersId | ✅ | ✅ | ✅ |
PatchListsIdMembersIdNotesId | ✅ | ||
PatchListsIdMergeFieldsId | ✅ | ||
PatchListsIdSegmentsId | ✅ | ||
PatchListsIdWebhooksId | ✅ | ||
PostListMemberEvents | ✅ | ||
PostListMemberTags | ✅ | ||
PostLists | ✅ | ||
PostListsId | ✅ | ||
PostListsIdInterestCategories | ✅ | ||
PostListsIdInterestCategoriesIdInterests | ✅ | ||
PostListsIdMembers | ✅ | ✅ | ✅ |
PostListsIdMembersHashActionsDeletePermanent | ✅ | ||
PostListsIdMembersIdNotes | ✅ | ||
PostListsIdMergeFields | ✅ | ||
PostListsIdSegments | ✅ | ||
PostListsIdSegmentsId | ✅ | ||
PostListsIdSegmentsIdMembers | ✅ | ||
PostListsIdSignupForms | ✅ | ||
PostListsIdWebhooks | ✅ | ||
PreviewASegment | ✅ | ||
PutListsIdMembersId | ✅ | ||
SearchTagsByName | ✅ |
Request | Tested | Documented | watchOS |
---|---|---|---|
GetTemplates | ✅ | ||
GetTemplatesId | ✅ | ||
GetTemplatesIdDefaultContent | ✅ | ||
PatchTemplatesId | ✅ | ||
PostTemplates | ✅ | ✅ | ✅ |
Request | Tested | Documented | watchOS |
---|---|---|---|
DeleteCampaignFoldersId | ✅ | ||
GetCampaignFolders | ✅ | ||
GetCampaignFoldersId | ✅ | ||
PatchCampaignFoldersId | ✅ | ||
PostCampaignFolders | ✅ |
Request | Tested | Documented | watchOS |
---|---|---|---|
DeleteTemplateFoldersId | ✅ | ||
GetTemplateFolders | ✅ | ||
GetTemplateFoldersId | ✅ | ||
PatchTemplateFoldersId | ✅ | ||
PostTemplateFolders | ✅ | ||
DeleteTemplatesId | ✅ |
Request | Tested | Documented | watchOS |
---|---|---|---|
GetSearchCampaigns | ✅ |
Request | Tested | Documented | watchOS |
---|---|---|---|
GetSearchMembers | ✅ |
Request | Tested | Documented | watchOS |
---|---|---|---|
GetReports | ✅ | ||
GetReportsId | ✅ | ||
GetReportsIdAbuseReportsId | ✅ | ||
GetReportsIdAbuseReportsIdId | ✅ | ||
GetReportsIdAdvice | ✅ | ||
GetReportsIdClickDetails | ✅ | ||
GetReportsIdClickDetailsId | ✅ | ||
GetReportsIdClickDetailsIdMembers | ✅ | ||
GetReportsIdClickDetailsIdMembersId | ✅ | ||
GetReportsIdDomainPerformance | ✅ | ||
GetReportsIdEcommerceProductActivity | ✅ | ||
GetReportsIdEepurl | ✅ | ||
GetReportsIdEmailActivity | ✅ | ||
GetReportsIdEmailActivityId | ✅ | ||
GetReportsIdLocations | ✅ | ||
GetReportsIdOpenDetails | ✅ | ||
GetReportsIdOpenDetailsIdMembersId | ✅ | ||
GetReportsIdSentTo | ✅ | ||
GetReportsIdSentToId | ✅ | ||
GetReportsIdSubReportsId | ✅ | ||
GetReportsIdUnsubscribed | ✅ | ||
GetReportsIdUnsubscribedId | ✅ |
Request | Tested | Documented | watchOS |
---|---|---|---|
GetRoot | ✅ |
These are the next set of API for which migrating to watchOS is desired as well as more robust testing and documentation. If you have any requests feel free to submit an issue or pull-request to improve current support.
Request | Tested | Documented | watchOS |
---|---|---|---|
DeleteFileManagerFilesId | |||
DeleteFileManagerFoldersId | |||
GetFileManagerFiles | |||
GetFileManagerFilesId | |||
GetFileManagerFolders | |||
GetFileManagerFoldersId | |||
PatchFileManagerFilesId | |||
PatchFileManagerFoldersId | |||
PostFileManagerFiles | |||
PostFileManagerFolders |
Request | Tested | Documented | watchOS |
---|---|---|---|
DeleteBatchesId | |||
GetBatches | |||
GetBatchesId | |||
PostBatches | |||
DeleteBatchWebhookId | |||
GetBatchWebhook | |||
GetBatchWebhooks | |||
PatchBatchWebhooks | |||
PostBatchWebhooks |
Request | Tested | Documented | watchOS |
---|---|---|---|
ArchiveAutomations | |||
DeleteAutomationsIdEmailsId | |||
GetAutomations | |||
GetAutomationsId | |||
GetAutomationsIdEmails | |||
GetAutomationsIdEmailsId | |||
GetAutomationsIdEmailsIdQueue | |||
GetAutomationsIdEmailsIdQueueId | |||
GetAutomationsIdRemovedSubscribers | |||
GetAutomationsIdRemovedSubscribersId | |||
PatchAutomationEmailWorkflowId | |||
PostAutomations | |||
PostAutomationsIdActionsPauseAllEmails | |||
PostAutomationsIdActionsStartAllEmails | |||
PostAutomationsIdEmailsIdActionsPause | |||
PostAutomationsIdEmailsIdActionsStart | |||
PostAutomationsIdEmailsIdQueue | |||
PostAutomationsIdRemovedSubscribers |
These are the least priority set of API for which migrating to watchOS as well as robust testing and documentation have been prioritized. If you have any requests feel free to submit an issue or pull-request to improve current support.
Request | Tested | Documented | watchOS |
---|---|---|---|
GetActivityFeedChimpChatter |
Request | Tested | Documented | watchOS |
---|---|---|---|
GetAuthorizedApps | |||
GetAuthorizedAppsId |
Request | Tested | Documented | watchOS |
---|---|---|---|
DeleteConnectedSitesId | |||
GetConnectedSites | |||
GetConnectedSitesId | |||
PostConnectedSites | |||
PostConnectedSitesIdActionsVerifyScriptInstallation |
Request | Tested | Documented | watchOS |
---|---|---|---|
GetConversations | |||
GetConversationsId | |||
GetConversationsIdMessages | |||
GetConversationsIdMessagesId |
Request | Tested | Documented | watchOS |
---|---|---|---|
PostCustomerJourneysJourneysIdStepsIdActionsTrigger |
Request | Tested | Documented | watchOS |
---|---|---|---|
DeleteEcommerceStoresId | |||
DeleteEcommerceStoresIdCartsId | |||
DeleteEcommerceStoresIdCartsLinesId | |||
DeleteEcommerceStoresIdCustomersId | |||
DeleteEcommerceStoresIdOrdersId | |||
DeleteEcommerceStoresIdOrdersIdLinesId | |||
DeleteEcommerceStoresIdProductsId | |||
DeleteEcommerceStoresIdProductsIdImagesId | |||
DeleteEcommerceStoresIdProductsIdVariantsId | |||
DeleteEcommerceStoresIdPromocodesId | |||
DeleteEcommerceStoresIdPromorulesId | |||
GetEcommerceOrders | |||
GetEcommerceStores | |||
GetEcommerceStoresId | |||
GetEcommerceStoresIdCarts | |||
GetEcommerceStoresIdCartsId | |||
GetEcommerceStoresIdCartsIdLines | |||
GetEcommerceStoresIdCartsIdLinesId | |||
GetEcommerceStoresIdCustomers | |||
GetEcommerceStoresIdCustomersId | |||
GetEcommerceStoresIdOrders | |||
GetEcommerceStoresIdOrdersId | |||
GetEcommerceStoresIdOrdersIdLines | |||
GetEcommerceStoresIdOrdersIdLinesId | |||
GetEcommerceStoresIdProducts | |||
GetEcommerceStoresIdProductsId | |||
GetEcommerceStoresIdProductsIdImages | |||
GetEcommerceStoresIdProductsIdImagesId | |||
GetEcommerceStoresIdProductsIdVariants | |||
GetEcommerceStoresIdProductsIdVariantsId | |||
GetEcommerceStoresIdPromocodes | |||
GetEcommerceStoresIdPromocodesId | |||
GetEcommerceStoresIdPromorules | |||
GetEcommerceStoresIdPromorulesId | |||
PatchEcommerceStoresId | |||
PatchEcommerceStoresIdCartsId | |||
PatchEcommerceStoresIdCartsIdLinesId | |||
PatchEcommerceStoresIdCustomersId | |||
PatchEcommerceStoresIdOrdersId | |||
PatchEcommerceStoresIdOrdersIdLinesId | |||
PatchEcommerceStoresIdProductsId | |||
PatchEcommerceStoresIdProductsIdImagesId | |||
PatchEcommerceStoresIdProductsIdVariantsId | |||
PatchEcommerceStoresIdPromocodesId | |||
PatchEcommerceStoresIdPromorulesId | |||
PostEcommerceStores | |||
PostEcommerceStoresIdCarts | |||
PostEcommerceStoresIdCartsIdLines | |||
PostEcommerceStoresIdCustomers | |||
PostEcommerceStoresIdOrders | |||
PostEcommerceStoresIdOrdersIdLines | |||
PostEcommerceStoresIdProducts | |||
PostEcommerceStoresIdProductsIdImages | |||
PostEcommerceStoresIdProductsIdVariants | |||
PostEcommerceStoresIdPromocodes | |||
PostEcommerceStoresIdPromorules | |||
PutEcommerceStoresIdCustomersId | |||
PutEcommerceStoresIdProductsIdVariantsId |
Request | Tested | Documented | watchOS |
---|---|---|---|
GetAllFacebookAds | |||
GetFacebookAdsId |
Request | Tested | Documented | watchOS |
---|---|---|---|
DeleteLandingPageId | |||
GetAllLandingPages | |||
GetLandingPageId | |||
GetLandingPageIdContent | |||
PatchLandingPageId | |||
PostAllLandingPages | |||
PostLandingPageIdActionsPublish | |||
PostLandingPageIdActionsUnpublish |
Request | Tested | Documented | watchOS |
---|---|---|---|
CreateVerifiedDomain | |||
DeleteVerifiedDomain | |||
GetVerifiedDomain | |||
GetVerifiedDomains | |||
VerifyDomain |
Thanks to Yonas Kolb for his work on a variety of project but especially Swaggen.
This code is distributed under the MIT license. See the LICENSE file for more info.