Introduction
Welcome to the Salesfly® REST API.
Endpoints
All API requests are made to api.salesfly.com
and all requests are served over HTTPS.
https://api.salesfly.com/v1
IMPORTANT
API calls made over plain HTTP are not supported and will fail.
Versioning
As we develop future versions of our API that are not backwards-compatible, we will leave the old version running and create a new url for the latest version. We will retain support for obsolete versions for a generous period of time and will send email notifications of any changes.
The current API version is v1
. Future versions will be v2, v3, etc.
Authentication
All requests to the API must be authenticated with an API key. You can submit the API key in the HTTP request header, or you can specify the access token as a HTTP URL query parameter.
TIP
If you do not have an API Key, you can easily generate one by heading over to the API settings page.
In the HTTP Authorization header:
Authorization: Bearer YOUR-API-KEY
In the URL
Add api_key=YOUR-API-KEY
to the URL:
https://api.salesfly.com/v1/geoip/8.8.8.8?api_key=YOUR-API-KEY
IMPORTANT
API requests without authentication will fail.
Errors
Salesfly uses conventional HTTP status response codes to indicate the success or failure of an API request. In general: Status codes in the 2XX
range indicate success. Status codes in the 4XX
range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a charge failed, etc.). Status codes in the 5XX
range indicate an error with Salesfly's servers (these are rare).
The body of an error response:
{
"status": 404,
"success": false,
"code": "err-ip-not-found",
"message": "IP address not found"
}
status
is the HTTP status code, success
is true upon success and false if there was an error. message
is a descriptive error message string, and finally code
is the error code (see below for a list of error codes).
Error codes
Code | Description |
---|---|
err-access-denied | Access was denied to the API endpoint. Check your API key permissions or IP address restrictions. |
err-account-suspended | Your account has been suspended due to a payment problem. |
err-bad-gateway | Bad gateway (DNS or routing problem, 502). |
err-date-before-2000 | Date must be after January 1, 2000. |
err-date-must-be-in-the-past | Date must be in the past. |
err-https-required | You must use HTTPS to access the API. |
err-internal-server-error | Something went wrong on our side (500). |
err-invalid-amount | Amount must be a number larger than zero (ie. 12345.00). |
err-invalid-apikey | The API key provides was not valid (wrong format or not found in our database). |
err-invalid-base-currency | Invalid base currency. |
err-invalid-date | Invalid date (format must be YYYY-MM-DD). |
err-invalid-dest-currency | Invalid destination currency. |
err-invalid-end-date | Invalid end date (format must be YYYY-MM-DD). |
err-invalid-ip | You provided an invalid IP address for Geolocation lookup. |
err-invalid-param | The request has a missing or wrong input parameter. |
err-invalid-request | The request sent to the API server was incomplete or had invalid parameters. |
err-invalid-sender | Not allowed to send from this address. |
err-invalid-source-currency | Invalid source currency. |
err-invalid-start-date | Invalid start date (format must be YYYY-MM-DD) and must be after end date. |
err-invalid-timespan | Max timespan is one year (365 days). |
err-ip-not-found | The specified IP address was not found in the GeoIP database. |
err-malware-detected | Malware has been detected in outgoing mail. |
err-missing-apikey | You forgot to provide an API key. |
err-missing-dkim | Missing or invalid DKIM DNS record for sending domain. |
err-missing-dmarc | Missing or invalid DMARC DNS record for sending domain. |
err-missing-spf | Missing or invalid SPF DNS record for sending domain. |
err-no-currency-data | No currency data for chosen date. |
err-no-data | No data available. |
err-no-recipients | No valid mail recipients. |
err-no-route | Route not found. |
err-not-modified | Not modified (304) |
err-pro-feature | This feature is not available for your plan (upgrade to a paid plan to continue). |
err-publishable-apikey | This API call cannot be made with a publishable key. |
err-rate-limit | Too may requests - rate limit exceeded. |
err-same-currency | Source and destination currencies must be different. |
err-service-unavailable | Service unavailable (503). |
err-spam-detected | Outgoing mail has been flagged as spam. |
err-too-many-recipients | Too many mail recipients. |
err-unexpected | Unexpected response from server. |
err-usage-exceeded | You have exceeded your API usage limit. |
Rate limits
API access rate limits are applied at a per-key basis in unit time. Access to the API using a key is limited to 60 requests per minute for the Lite plan, and 600 requests per minute for paid plans. In addition, every API response is accompanied by the following set of headers to identify the status of your consumption.
Header | Description |
---|---|
X-RateLimit-Limit | The maximum number of requests that the consumer is permitted to make per minute. |
X-RateLimit-Remaining | The number of requests remaining in the current rate limit window. |
X-RateLimit-Reset | The time at which the current rate limit window resets in UTC epoch seconds. |
X-RateLimit-Delay | The number of seconds until the rate counter is reset (only present when limit has been exceeded). |
Once you hit the rate limit, you will receive a response similar to the following JSON, with a status code of 429
.
{
"status": 429,
"success": false,
"code": "err-rate-limit",
"message": "Too may requests - rate limit exceeded"
}
Making requests
The API returns data in either JSON or XML format. JSON is the default format. You specify the format of the return data using the Accept
header.
You can also specify the data format using HTTP URL query parameter format
. This is particulary useful for GET requests where you cannot set HTTP headers.
The Accept header:
Accept: application/json
or
Accept: application/xml
In the URL
Add format=json
or format=xml
to the URL:
https://api.salesfly.com/v1/geoip/8.8.8.8
?api_key=YOUR-API-KEY
&format=json
or
https://api.salesfly.com/v1/geoip/8.8.8.8
?api_key=YOUR-API-KEY
&format=xml
POSTing data
For POST/PATCH/PUT requests you can upload data using JSON, XML, form URL encoded or multipart form data. You specify the type of content using the Content-Type
header.
JSON:
Content-Type: application/json
{
"from": "me@example.com",
"to": ["john@example.com", "steve@example.com"],
"subject": "Test",
"text": "This is a test"
}
XML:
Content-Type: application/xml
You must enclose an XML request inside a <request>
tag.
<request>
<from>me@example.com</from>
<to>john@example.com</to>
<to>steve@example.com</to>
<subject>Test</subject>
<text>This is a test</text>
</request>
Form URL encoded:
Content-Type: application/x-www-form-urlencoded
Multipart form data:
Content-Type: multipart/form-data; boundary="someboundary"
Responses
Single-item responses will be in this format:
JSON:
{
"status": 200,
"success": true,
"data": {
"id": 1,
"name": "test"
}
}
or XML:
<result>
<status>200</status>
<success>true</success>
<data>
<id>1</id>
<name>test</name>
</data>
</result>
Most endpoints return a single model of data.
Multi-item responses will be in this format:
JSON:
{
"status": 200,
"success": true,
"data": [
{
"id": 1,
"name": "test1"
},
{
"id": 2,
"name": "test2"
}
]
}
or XML:
<result>
<status>200</status>
<success>true</success>
<dataset>
<data index="0">
<id>1</id>
<name>test1</name>
</data>
<data index="1">
<id>2</id>
<name>test2</name>
</data>
</dataset>
</result>
NOTE: The data index starts from zero for XML arrays.
JSON Callbacks
The Salesfly API also supports JSONP callbacks. To use this feature, add callback=CALLBACK_FUNCTION
to the HTTP request, and the result set will be returned as the callback function you specified.
Example request:
https://api.salesfly.com/v1/geoip/8.8.8.8
?api_key=YOUR-API-KEY
&callback=CALLBACK_FUNCTION
Example response:
CALLBACK_FUNCTION({
"data": {
"country_code": "US"
},
"status": 200,
"success": true
})
ETags / Cache Control
The ETag or entity tag is part of the HTTP protocol. It is one of several mechanisms that HTTP provides for Web cache validation, which allows a client to make conditional requests. This allows caches to be more efficient and saves bandwidth, as a Web server does not need to send a full response if the content has not changed.
An ETag is an opaque identifier assigned by a web server to a specific version of a resource found at a URL. If the resource content at that URL ever changes, a new and different ETag is assigned. Used in this manner ETags are similar to fingerprints, and they can be quickly compared to determine if two versions of a resource are the same or not.
The Currency API supports ETags, and this allows you to check whether or not currency rates have changed since your last API request. If the rates have not been modified, your API response will be considerably smaller in size than if they have. Practically, ETags provide a mechanism to cache exchange rate data as long as it is not updated.
This is how you use it in your client code:
1. Save the latest API response
Each request to the Currency API will include an ETag and a Date in the HTTP response headers.
The Etag is a unique alphanumeric identifier for the data returned in the response, and the Date is the time at which the data was last modified. The date and time format is defined in RFC7231.
Example:
Date: Mon, 16 Mar 2020 10:15:46 GMT
ETag: "e33161ba2244ff74b9c9f1739cebec80"
2. Add the "If-None-Match" header
The next time you make a request to the same API URL, add the If-None-Match
header, with the value set to the ETag you saved from the previous request. Remember to wrap the value in double quotation '"' marks.
You also need to send an If-Modified-Since
header, which will be the Date value from the last successful request.
If continue to use the example above, your two request headers would look like this:
If-None-Match: "e33161ba2244ff74b9c9f1739cebec80"
If-Modified-Since: Mon, 16 Mar 2020 10:15:46 GMT
3. If not modified, use cached data
If the data have not been updated since your last request, the response status code will be 304 – Not Modified
, and no data will be returned.
You can now safely use the cached API response from your previous successful request.
4. If changed, cache the new response
If the rates have been modified since your last request, the latest data will returned as usual, along with new ETag
and Date
headers.
Go back to step 1.
NOTE
Although ETags help reduce bandwidth for your users, all API requests still count towards your monthly usage – even if the data has not changed since your last request.
Formatted output
By default the output from the Salesfly API is not formatted in any way. In order to improve readability you can specify that you want the output to be formatted and indented.
To enable this feature, add indented=true
to the API request:
https://api.salesfly.com/v1/geoip/8.8.8.8
?api_key=YOUR-API-KEY
&indented=true
NOTE
Indented output is larger than normal output and should only be used for debugging purposes.
Legal notices
Your use and access to the API is expressly conditioned on your compliance with the policies, restrictions, and other provisions related to the API set forth in our Terms of Service and the Privacy Policy, in all uses of the API. If we believes that you have or attempted to violate any term, condition, or the spirit of these policies or agreements, your right to access and use the API may be temporarily or permanently revoked.
Salesfly is a registered trademark of UAB Salesfly.