The Nutshell REST API documentation can be found at developers.nutshell.com.
We provide an industry-standard JSON-RPC API that allows you to retrieve and modify your data at any time. Nutshell also provides a minimal HTTP POST API for simple web-to-lead forms.
The data you store in Nutshell belongs to you, and we've designed our open APIs to make it possible for you to work with it however you wish. Please contact us with any questions on using the API.
The Nutshell JSON-RPC API is available via the JSON-RPC protocols. Nearly all modern programming languages have libraries for interfacing with a JSON-RPC API.
Nutshell uses JSON-RPC v2.0 and supports named parameters. An SMD (Service Mapping Description) is available via a GET request to the API endpoint.
The Nutshell API uses HTTP Basic authentication. All API calls, except requests for JSON-RPC's SMD file, must include the Authentication
header.
The username for authentication is either your company's domain or a specific user's email address (see the Impersonation section, below). The password is always an API key.
The Nutshell API is accessible only via HTTPS to ensure that API keys and other sensitive information remain secure.
Here's an example cURL command that retrieves Lead-1000 from Nutshell's JSON-RPC API:
curl -u <domain or username>:<api token> \
-d '{ "id": "<id>", "method": "getLead", "params": { "leadId": 1000 } }' \
https://app.nutshell.com/api/v1/json
Permissions
Impersonation
Each API key may allow or disallow "impersonation".
If impersonation is allowed for an API key, the API consumer may authenticate using any valid user's email address as the username. Any changes the API consumer makes will be logged as if that user had made the changes directly.
If impersonation is not permitted, the API consumer must authenticate using an email within the company's Nutshell application as the username. Any changes the API consumer makes will be logged using the API key's name (set when the key was created).
Web-only
A web-only API key is used to create basic HTML forms using Nutshell's minimal HTTP POST API. Web-only API keys are created with the expectation that they may become public. They cannot be used for authentication to the JSON-RPC API.
Web-only API keys do not use HTTP Basic authentication, nor is impersonation available.
HTTP response codes
The Nutshell API will return the HTTP status code 401 (authorization required) if the Authentication
header is missing or the username or API key is invalid.
The API will return an HTTP 200 status if the Authentication
header is valid or authentication is not required.
We make every effort to make your data as accessible as possible. To maintain a high quality of service, we rate limit a few large requests. Most notably, find
(e.g. findLeads()
) requests with non-stub responses (stubResponses = true
). To a lesser extent, excessive get
requests (e.g. getContact()
) are also rate-limited.
The degree of rate-limiting may change dependent on current conditions. We do not rate-limit any incoming add or edit requests. Contact us if you have any questions about API usage.
At its core, Nutshell tracks objects such as contacts and accounts (known in the Nutshell world as "entities") and the relationships ("maps") between these entities.
Entities returned by the API contain an entityType
field which tells API consumers about the entity. (Examples of entityTypes include Users
, Teams
, Accounts
, Contacts
.)
Note on Contacts/People and Accounts/Companies: you might notice that Nutshell refers to People and Companies, but the API uses the terminology Contacts and Accounts. Nutshell has made a change to the way we refer to those two top-level entity types, but the API is still configured to use the previous "nouns" Contacts and Accounts.
To show related entities, the API embeds stubs of these relationships in API responses. For example, a lead returned by the API has an array called contacts
which includes a stub for each contact related to the Lead.
Stubs
For certain API calls, it does not make sense (for performance or bandwidth reasons) for Nutshell to return a full entity complete with all its details. In these cases, the Nutshell API returns "stub" responses.
A stub includes only the most important information about an entity. A stub is indicated by the property "stub": true
on the entity.
Stubs use fewer server resources and consume less bandwidth - especially important if your API consumer is a mobile device.
This is a stub for a hypothetical lead:
{
"stub": true,
"id": 145,
"entityType": "Leads",
"rev": "5",
"name": "Lead–145",
"status": 10,
"completion": 100,
"value": {
"currency": "USD",
"amount": 1780
},
"primaryAccountName": "Auto-Owners Insurance",
"dueTime": "2010-07-18T12:00:00+0000",
"closedTime": "2010-07-18T12:00:00+0000"
}
Stubs are typically returned when an entity is embedded inside another for an API response (for example, an account or contact included in a lead) and optionally for some find*
and search*
API methods.
Entity types
Use the entityType
key on a given API response object to determine its type. Entity types returned by the API are strings, and they are English plural nouns. This is an incomplete list of entityTypes returned by the API, with links to documentation on their structure.
Notes do not currently return their entityType. They may appear in the notes
array for Accounts, Contacts, and Leads; and a single note may appear in the logNote
key for an Activity.
Relationships
Leads are the single entity type in Nutshell which has the most relationships. Each Lead can be associated with multiple Processes, Sources, Competitors, Products, Contacts, Accounts, and Notes.
Each Lead also includes exactly one:
creator
(a User)
primaryAccount
(an Account)
milestone
(a Milestone)
market
(a Market)
assignee
(a User or Team)
Activities have a few relationships. They include one Activity_Type and may include one User (if the Activity has been logged; in the loggedBy
key). Activities also have a one-to-many relationship with their participants. Participants may be Users or Contacts.
Accounts and Contacts have a two-way one-to-many relationship. Each Account may be related to multiple Contacts; similarly, each Contact may be related to multiple Accounts. Each Account knows about its Contacts and vice-versa. Because of this two-way awareness, Account-Contact relationships may be modified, added, or removed using both the editContact
and editAccount
API methods.
Previously Accounts and Contacts mapped to a Lead contained a relationship field consisting of an optional text description of the relationship. In October 2012 this field was removed and is replaced with a single description field on the Account or Contact directly.
Retrieving an Entity
To retrieve an entity from the API, use one of the get*
methods listed in the API method index. These methods take an entity ID and (optionally) a rev identifier. (See the Revs and ETags documentation for additional information about revs and caching.)
Expected Response
The response for any get*
method is typically a dictionary representation of the requested entity. For a detailed description of exactly which fields may be returned for each entity, see the corresponding documentation from the API response index.
For example, the array returned by getLead
is documented in Lead.
If an entity is not returned, the response will be an error message or a notice that your currently cached entity is still valid.
Editing an Entity
To edit an entity, use one of the edit*
methods listed in the API method index. These methods take an entity ID, a rev identifier, and an array containing new/updated values for the entity.
The rev identifier is mandatory for the edit*
methods. See "Revs", below, for an overview of how revs are used in editing an entity.
Expected Responses
The response for any edit*
method is typically a dictionary representation of the updated entity. (See "Expected Responses" for retrieving an entity, above.)
If an entity is not returned, the response will be an error message or a notice that you cannot edit the entity because your currently cached entity is invalid. (See "Revs", below, for an overview of how revs are used in editing an entity.)
Multi-Value Fields
Many entities have fields which can contain more than one value. For example, a Contact may have multiple addresses and phone numbers; and a Lead may have multiple Contacts.
Each of these fields, if present in a response, will include one value called --primary
. This will be a duplicate of another value in the multi-value field; it represents the primary value (for example, a Contact's primary phone number).
Editing Multi-Value Fields
When you wish to add a value (for example, an additional phone number) to one of these multi-value fields, you must also include all preexisting values in that field. The edit*
methods replace all existing values with whatever value(s) you supply in your API call.
This behavior allows you to delete values from multi-value fields using the edit*
family of methods.
If a multi-value field is not included in the "changes" array you pass to the edit method, the preexisting values are not affected.
This behavior does not apply to fields that can only contain a single value (such as a Contact's name
).
Custom Fields
Certain entity types (currently Leads, Accounts, and Contacts) support custom fields, which can be viewed and edited just like regular fields. In order to prevent name collisions with built-in fields, custom fields are contained within a dictionary with the key customFields
.
Custom fields are rendered just like regular fields of the same type. Here's an example response for a getLead
request on a lead with a currency custom field named "Budget" and a text custom field named "Reference ID":
"result": {
"id": 1653,
"entityType": "Leads",
...
"customFields": {
"Reference ID": "999-99-9999",
"Budget": {
"currency": "USD",
"amount": "200"
}
},
...
}
Editing Custom Fields
Editing custom fields can be done by including a customFields
dictionary in the changes array you pass to the edit*
method. To update or add a custom field, add an entry to customFields
with the key set to the custom field's name and the value to the desired value. To delete a custom field value, do the same, but set the value to null
.
Here's an example JSON-RPC request that will remove the value for the "Reference ID" field and change the value for the "Budget" field to €40.50 for the above lead:
{
"jsonrpc": "2.0",
"method": "editLead",
"params": {
"leadId": "1653",
"rev": "9",
"lead": {
"customFields": {
"Budget": {
"currency": "EUR",
"amount": "40.50"
},
"Reference ID": null
}
}
},
"id": "a"
}
Revs
Revs are Nutshell's approach to application-level cache control. The Nutshell API issues a revision identifier (rev
key) as part of its response each time you retrieve an entity.
When you call an edit*
method, you must include the rev you have cached for the entity you intend to edit. If the entity has been changed on the server since you last retrieved it, the API will not let you make your changes. This prevents the possibility of accidental data loss.
For additional information on revs, see the Revs and ETags documentation.
The Nutshell API offers many find and search methods which your application can use to retrieve data.
Find vs. Search
The find*
methods are used to query the Nutshell database for a set of results.
Some find methods (e.g., findAccountTypes
) do not take query parameters; they simply return all possible entities according to the sorting and pagination options you specify. Other find methods (e.g., findAccounts
) accept a query
parameter. Each find method accepts a specific set of query keys; this is documented in detail in the API documentation for each method.
Some find methods can optionally retrieve stub entities for faster responses, but by default all find methods return full entities.
The search*
methods are used to quickly find results matching a given search query string.
These search methods (e.g., searchContactsAndUsers
) use the same high-performance search engine that Nutshell uses to power its find-as-you-type feature. The search methods always return stub entities for extremely fast results.
See the entities & relationships documentation for more information on stubs.
Pagination
All find*
methods use the same simple interface for pagination. Each method accepts four optional parameters which control pagination: orderBy
, orderDirection
, limit
, and page
.
orderBy
is the column by which the search results should be sorted. Each find method has its own default (usually name
) which is sensible for most queries.
orderDirection
may be one of ASC
or DESC
. Default is ASC
.
limit
sets the number of results returned per page. Default is 50.
page
sets the results page number. Default is 1.
If the page your application retrieves has fewer entities than the limit you sent with the query, you've retrieved the last page of results.
Find and Search Methods
The Nutshell database can be queried with any of these API methods:
findAccounts
findAccountTypes
findActivities
findActivityTypes
findCompetitors
findContacts
findDelays
findIndustries
findLead_Outcomes
findLeads
findMarkets
findAudiences
findMilestones
findOrigins
findProducts
findSettings
findSources
findTeams
findUsers
searchAccounts
searchCompetitors
searchContacts
searchContactsAndUsers
searchProducts
searchSources
searchUniversal
searchUsersAndTeams
The Nutshell API offers solutions for cache validation at the network and application levels.
ETags
Nutshell uses HTTP ETags as a solution for cache validation at the network level. The JSON-RPC API uses ETags as specified in HTTP 1.1, and is useful for simple API optimizations at the network layer.
When a get*
or find*
method is requested via JSON-RPC with the current ETag in the If-None-Match
header, the server will respond with an empty response and a 304
(not-modified) HTTP status. If the document has changed, the response will contain the full requested contented and the new Etag
header.
Note that ETags are currently not relevant (and ignored) for edit methods. Use the rev
key documented below for version checking.
Revs
Revs are Nutshell's approach to application-level cache control.
The Nutshell API issues a revision identifier (rev
key) as part of its response each time you retrieve an entity. Your API client should store this identifier with its cache of the entity.
Note: Revs may appear to be incrementing integers, but your application should treat revs as strings to avoid potential issues in the future.
When you call a potentially-destructive API method (for example, editContact
), you must include the rev that you have cached for the entity you are modifying. If that rev doesn't match the rev on the server, the entity has been updated on the server since you last retrieved it. In that case, you won't be allowed to make the change you requested; you'll need to download the latest version of the entity, resolve any conflicts, and retry your edits.
If the entity has been modified since you last downloaded it, you'll get the error "rev key is out-of-date":
"error": {
"code": 409,
"message": "rev key is out-of-date",
"data": NULL
}
When you call a non-destructive API method (for example, getContact
) to retrieve an entity you already have cached, you can send the rev that you have for that entity. If the entity hasn't been modified on the server, the API will not return the whole entity again. Instead, it'll include a _notModified
attribute in the result:
"result": {
"entityName": "Contacts",
"id": 10,
"rev": "5",
"_notModified": true
}
Sometimes, you may want to perform a destructive edit or explicitly ignore Nutshell's revs for some other reason. This is possible, though you should exercise caution when using this functionality. To tell the Nutshell API to ignore revs, pass the string "REV_IGNORE
" as the rev of the entity you intend to edit.
Several components of the Nutshell API support uploading and downloading files. This document outlines the general workflow.
Where files are available
- Logged activities may have one or more attachments, representing the audio or video log.
- Accounts, Contacts, and Leads can have one or more attached files
- On-demand ZIP backups can be generated and downloaded
We plan to add additional support for file attachments in the near future.
Retrieving attached files
Logged activities contain a logNote
property, an object which may have one or more file objects in its files
array. Multiple encodings are created after a file has been uploaded and processed.
Accounts, Contacts, and Leads have a file
property, which contains an array of files associated with this lead, typically uploaded via the web interface.
Sample file object
{
"entityType": "Files",
"id": 1234,
// Where to download this file via HTTPS
"uri": "https://app.nutshell.com/file/api/1234",
"name": "activity0_log_file_1322783452",
// An accurate MIME representation of this file
"mime": "video\/quicktime",
"rev": "ff6ae801b9584bb37b48d1c6273427a5942385f5",
// Size of this file in bytes
"size": 840464,
// A mime-like internal representation, primarily for our mobile apps
"clientType": "video\/iphone",
// Duration in ms
"duration": 8327
}
Downloading actual file data
After retrieving the file object documented above, use the object's uri
key as the endpoint for the file. You will need to use the same HTTP basic authentication that you use to access the file. Note that these endpoints support HTTP Range:
requests, useful when accessing media for HTTP streaming.
Uploading files
Uploading files to Nutshell is a two-part process. First, you will edit the entity, providing the metadata for the file you are about to upload. The response from Nutshell will include a URI resource, to which you should POST
the file. The process outlined below is the same for any Nutshell request that allows for uploads. (Currently editAccount()
, editContact()
, editLead()
, and editActivity()
)
1. Edit a lead to indicate a new file for upload
{
"method": "editLead",
"id": "1234",
"params": {
"leadId": 24455,
"rev": "rev",
"lead": {
"file": [
{
"entityType": "Files",
"name": "my_file_to_upload.txt"
}
]
}
}
}
2. Examine the response to editLead()
for the URL to which you should POST
{
"id": "1234",
"error": null,
"result": {
"entityType": "Leads",
"id": 24455,
...
"file": [
{
"entityType": "Files",
"id": 5678,
// this is the URL to post your file
"uri": "https://app.nutshell.com/file/api/5678",
"name": "my_file_to_upload.txt",
"mime": "",
"rev": "",
"size": 0,
"clientType": null
}
]
}
}
3. Post your file to the provided URL
After examining the response for the correct URI to upload your new file, you should create a simple HTTP POST with the contents of your file. This should just be a simple multipart/form-data
POST, with file
as the key for your file's data. As with downloading a file, you should use your standard HTTP Basic authentication. Here's an example cURL command that uploads test.txt
to the file with the URI https://app.nutshell.com/file/api/65
:
curl -v -u : -F "file=@test.txt;type=text/plain" 'https://app.nutshell.com/file/api/65'
You should be able to immediately download the file from the same URL resource, with an HTTP 200
status, as a way of confirming a successful upload.
Subsequent requests to retrieve the lead will now include the MIME type and size for your newly-uploaded file.