Rungopher API v1.3
https://portal.rungopher.com/api/v1
Conventions
- All calls require input of type
application/json
, unless otherwise indicated. - All calls return output of type
application/json
, unless otherwise indicated.
Errors
HTTP status codes have the usual meaning.
Errors are returned as JSON payload as well, but with a HTTP status code other
than 200 OK
.
Code | Reason |
---|---|
401 | Not logged in |
400 | Bad input |
403 | Action denied |
404 | Entity the action is applied to is not found, eg. campaign was not found |
500 | Any other server error |
See error string for actual error details, for example:
{
"errors": [ "No such campaign" ]
}
Authentication
The RunGopher API requires an API key for authentication. Please contact RunGopher support and get an API key for your account.
All requests should send this API key in the request header as so:
ApiKey: <yourApiKey>
Campaign Templates
GET api/v1/template
Get names and descriptions of all templates that can be used to create a campaign.
Response
[
{
"category": "General",
"name": "AcceptDecline",
"displayName": "Accept or Decline",
"description": "This campaign template asks the contact if they are interested in an event and categorizes the responses.",
"costPerContact": 0.34
},
{
"category": "Charities",
"name": "TellYourFriends",
"displayName": "Tell Your Friends",
"description": "This solution prepares a template sms message that the recipient can then forward on to friends.",
"costPerContact": 0.56
}
]
Attributes
Attribute | Type | Description |
---|---|---|
category |
string | One of General , Charities , Marketing |
name |
string | The name of the template. You will need to use this to create a campaign from this template |
displayName |
string | A friendly string to display to users |
description |
string | Some info about what function this template performs |
diagramUrl |
string | A link to a public google slide showing the structure of this template |
costPerContact |
decimal | The dollar amount the account holder will be charged for each contact started as a part of this campaign |
Campaigns
POST api/v1/campaign
Creates a new campaign using the template and parameters specified.
Request
{
"name": "AcceptDecline",
"title": "T1001: My Great Event Opt In",
"transitionEmail": "mark.hingston@rungopher.com"
}
Response
{
"id": 15,
"title": "T1001: My Great Event Opt In",
"campaignToken": "143-dfvsm-3r3ndkd",
"state": "draft",
"transitionEmail": "mark.hingston@rungopher.com",
"costPerContact": 0.34,
"costPerExtraSms": 0.04,
"costPerTransition": 0.05,
"smsContent": [
{
"name": "smsInterested",
"displayName": "A. Interested in offer?",
"content": "Hi! It's <Sue> from <My Company> here. Just wondering if you'd like to participate in our Great Event?"
},
{
"name": "smsAcceptReply",
"displayName": "B. Accept reply",
"content": "Thanks! We'll be in touch shortly"
}
],
"requiredFields": [
"firstName",
"lastName",
"mobile",
"contactId"
]
}
Request Attributes
Attribute | Type | Description |
---|---|---|
name |
string | The name of the template to use. This should be drawn from the name field in the api/v1/template call |
title |
string | The title the user wants to give the campaign |
transitionEmail |
string | An email address that will receive all responses that can't be auto-classified |
Campaign Attributes
Attribute | Type | Editable | Description |
---|---|---|---|
id |
integer | no | The id of the campaign |
title |
string | no | The title the user gave the campaign |
campaignToken |
string | no | A token that can be used later to reference the created campaign |
state |
string | no | One of draft , running , completed |
transitionEmail |
string | yes | An email address that will receive all responses that can't be auto-classified |
costPerContact |
decimal | no | The dollar amount the account holder will be charged for each contact started as a part of this campaign |
costPerExtraSms |
decimal | no | The dollar amount the account holder will be charged for each extra SMS segment (see Pricing section) |
costPerTransition |
decimal | no | The dollar amount the account holder will be charged for each transition reply they send (see Pricing section) |
SMS Attributes
Attribute | Type | Editable | Description |
---|---|---|---|
name |
string | no | Name used to identify this piece of sms content. Use this name when sending updates |
displayName |
string | no | Friendly name of this piece of content - to be shown to end users |
content |
string | yes | The actual SMS content. This must be between 1 to 1000 characters in length. |
Required fields
This is just full list of the fields required for each contact you add to this campaign. See Contact Upload below.
GET api/v1/campaign/<campaignId>
Get campaign details
Response
{
"id": 15,
"title": "T1001: My Great Event Opt In",
"campaignToken": "143-dfvsm-3r3ndkd",
"state": "draft",
"transitionEmail": "my-new-transition-email@me.com",
"costPerContact": 0.34,
"costPerExtraSms": 0.04,
"costPerTransition": 0.05,
"smsContent": [
{
"name": "smsInterested",
"displayName": "A. Interested in offer?",
"content": "Hi! It's <Sue> from <My Company> here. Just wondering if you'd like to participate in our Great Event?"
},
{
"name": "smsAcceptReply",
"displayName": "B. Accept reply",
"content": "Great! We'll give you a call shortly"
}
],
"requiredFields": [
"firstName",
"lastName",
"mobile",
"contactId"
]
}
GET api/v1/campaign
List all campaigns and their details
Response
[
{
"id": 15,
"title": "T1001: My Great Event Opt In",
"campaignToken": "143-dfvsm-3r3ndkd",
"state": "draft",
"transitionEmail": "my-new-transition-email@me.com",
"costPerContact": 0.34,
"costPerExtraSms": 0.04,
"costPerTransition": 0.05,
"smsContent": [
{
"name": "smsInterested",
"displayName": "A. Interested in offer?",
"content": "Hi! It's <Sue> from <My Company> here. Just wondering if you'd like to participate in our Great Event?"
},
{
"name": "smsAcceptReply",
"displayName": "B. Accept reply",
"content": "Great! We'll give you a call shortly"
}
],
"requiredFields": [
"firstName",
"lastName",
"mobile",
"contactId"
]
},
{
"id": 16,
"title": "T1003: My Great Event",
"campaignToken": "abc-123sm-3r3ndkd",
"state": "draft",
"transitionEmail": "my-new-transition-email@me.com",
"costPerContact": 0.15,
"costPerExtraSms": 0.04,
"costPerTransition": 0.05,
"smsContent": [
{
"name": "smsHello",
"displayName": "A. Hello",
"content": "Hi! It's <Sue> from <My Company> here. I hope your ready for the great event!"
}
],
"requiredFields": [
"firstName",
"lastName",
"mobile",
"contactId"
]
}
]
POST api/v1/campaign/<campaignId>
Edits a campaign
Request
{
"transitionEmail": "my-new-transition-email@me.com",
"smsContent": [
{
"name": "smsInterested",
"content": "Hi! It's Ben from BigEvents here. Just wondering if you'd like to participate in our Great Event?"
},
{
"name": "smsAcceptReply",
"content": "Great! We'll give you a call shortly"
}
]
}
Request criteria
transitionEmail
andsmsContent
are both optional. You can specify one or the other, or both.- If specified,
smsContent
must contain at least one object. smsContent
can specify multiplename
s to be edited, as list items. The list can be anywhere from 1 element long to editing all elements in the campaign at once.- Each
name
must appear only once in thesmsContent
list. - Each piece of SMS content must be between 1 and 1000 characters long.
Response
{
"id": 15,
"title": "T1001: My Great Event Opt In",
"campaignToken": "143-dfvsm-3r3ndkd",
"state": "draft",
"transitionEmail": "my-new-transition-email@me.com",
"costPerContact": 0.34,
"costPerExtraSms": 0.04,
"costPerTransition": 0.05,
"smsContent": [
{
"name": "smsInterested",
"displayName": "A. Interested in offer?",
"content": "Hi! It's Ben from BigEvents here. Just wondering if you'd like to participate in our Great Event?"
},
{
"name": "smsAcceptReply",
"displayName": "B. Accept reply",
"content": "Great! We'll give you a call shortly"
}
],
"requiredFields": [
"firstName",
"lastName",
"mobile",
"contactId"
]
}
Contact Upload
POST api/v1/campaign/<campaignId>/contact
Add a contact to a campaign and start that contact. Any of the attributes listed in the 'Contact Attributes' section can be added as part of a contact. The contacts list can contain anywhere from 1 up to 30,000 contacts.
Request
{
"mode": "live",
"contacts": [
{
"contactId": "1",
"firstName": "Mark",
"lastName": "Jones",
"mobile": "+61468403000"
},
{
"contactId": "2",
"firstName": "Chris",
"lastName": "Smith",
"mobile": "+61468403001"
}
]
}
Response
200 OK
response means that the submitted contacts were started successfully. started
indicates how many contacts were successfully started. You may also receive 0 or more warnings
after a successful contact start. Eg:
{
"started": 10,
"warnings": []
}
OR:
{
"started": 8,
"warnings": [
"Mobile number +61468403100 already exists in this campaign, skipped",
"Mobile number +61468403101 already exists in this campaign, skipped"
]
}
Attributes
Attribute | Type | Description |
---|---|---|
campaignId |
integer | The RunGopher id for this campaign. Visible in the url bar when browsing campaigns in the portal. Or retrieved by listing all campaigns using the API. |
mode |
string | Accepted values are: live or test . In test mode you are allowed to use the same mobile number multiple times in a campaign. In live mode you can not. |
Contact Attributes
Mandatory - Every contact you upload must have each of these
Attribute | Type | Description |
---|---|---|
contactId |
string | External ID, eg. from your CRM |
firstName |
string | The first name of the contact |
lastName |
string | The last name of the contact |
mobile |
string | The mobile number of the contact, preferrably of the form +61468403000 |
Solution Specific - You may need to define one or more of these for each contact
Attribute | Type | Description |
---|---|---|
email |
string | The email address of the contact |
weblink |
string | The link that you want the contact to click on and visit. This will be automatically shortened and tracked. |
addressToVerify |
string | The address that you would like to verify is correct. |
bouncedAddress |
string | A failed delivery address that you would like the contact to correct. |
upgradeAmount |
string | The amount of extra money you are asking the contact for. |
Custom Attributes - Sometimes used to add specifics to solutions. Totally optional
Attribute | Type |
---|---|
custom1 |
string |
custom2 |
string |
custom3 |
string |
custom4 |
string |
Notes
A max of 30,000 contacts can be uploaded in a single batch.
Also please be aware that if individual contacts contain invalid data they will be skipped and reported to you as warnings, as shown above. Thus, if many contacts have warnings RunGopher may return a large amount of warning data in the response.
Journey Contact Update
PUT api/v1/journey/<journeyId>/contact/<mobile>
Update a contact previously uploaded.
Request
{
"fields": {
"firstName": "Justin",
"lastName": "Vanier",
"custom1": "new custom value"
"promo.weblink": "https://example.com/m24j4F
}
}
Response
200 OK
response indicates the submitted fields were updated successfully.
Attributes
Attribute | Type | Description |
---|---|---|
journeyId |
integer | The RunGopher id for the journey. Visible in the url bar when browsing journeys in the portal. |
mobile |
string | The mobile number of the contact, preferably of the form 61468403000 (phone number, prefixed with country code, without the +). |
fields |
json object | The fields to update, and the values. Allowed fields are firstName , lastName , custom1 , custom2 , custom3 , custom4 , and any of the solution specific fields applicable to that journey (in the format campaignName .fieldName ). |
Pricing
Segments
Because of the headers required to combine multiple SMSes back into one at the receiving phone, SMS segments are broken up like:
If the SMS is 160 characters or less: Segments = 1
If the SMS is more than 160 characters: Segments = Character count / 153
Some examples:
Character count | Segments |
---|---|
150 | 1 |
160 | 1 |
161 | 2 |
306 | 2 |
310 | 3 |
Extra SMS Segments
RunGopher templates come with default text, which you will edit before using. If your edits to the default text or the injection of the details of your contacts (first name, last name, etc) causes an SMS to become one segment larger, you will be charged for that extra segment, at the specified extraSegmentCost
. Mulitple extra segments will incur multiple extraSegmentCost
for that SMS.
Transitions
When a RunGopher client replies to a transition email, an SMS is sent to the end customer's phone. You will be charged costPerTransition
for each SMS that is sent via this method.