restforce travis-ci ruby Rubygems

A ruby client for the Salesforce REST api.

5 years after


travis-ci Code Climate Dependency Status

Restforce is a ruby gem for the Salesforce REST api. It's meant to be a lighter weight alternative to the databasedotcom gem that offers greater flexibility and more advanced functionality.

Features include:

  • A clean and modular architecture using Faraday middleware and Hashie::Mash'd responses.
  • Support for interacting with multiple users from different orgs.
  • Support for parent-to-child relationships.
  • Support for aggregate queries.
  • Support for the Streaming API
  • Support for blob data types.
  • Support for GZIP compression.
  • Support for custom Apex REST endpoints.
  • Support for dependent picklists.
  • Support for decoding Canvas signed requests. (NEW!)

Documentation | Changelog


Add this line to your application's Gemfile:

gem 'restforce'

And then execute:

$ bundle

Or install it yourself as:

$ gem install restforce


Restforce is designed with flexibility and ease of use in mind. By default, all api calls will return Hashie::Mash objects, so you can do things like client.query('select Id, (select Name from Children__r) from Account').Children__r.first.Name.


Which authentication method you use really depends on your use case. If you're building an application where many users from different orgs are authenticated through oauth and you need to interact with data in their org on their behalf, you should use the OAuth token authentication method.

If you're using the gem to interact with a single org (maybe you're building some salesforce integration internally?) then you should use the username/password authentication method.

OAuth token authentication

client = :oauth_token => 'oauth token',
  :instance_url  => 'instance url'

Although the above will work, you'll probably want to take advantage of the (re)authentication middleware by specifying a refresh token, client id and client secret:

client = :oauth_token => 'oauth token',
  :refresh_token => 'refresh token',
  :instance_url  => 'instance url',
  :client_id     => 'client_id',
  :client_secret => 'client_secret'

Username/Password authentication

If you prefer to use a username and password to authenticate:

client = :username => 'foo',
  :password       => 'bar',
  :security_token => 'security token',
  :client_id      => 'client_id',
  :client_secret  => 'client_secret'

You can also set the username, password, security token, client id and client secret in environment variables:

export SALESFORCE_USERNAME="username"
export SALESFORCE_PASSWORD="password"
export SALESFORCE_SECURITY_TOKEN="security token"
export SALESFORCE_CLIENT_ID="client id"
export SALESFORCE_CLIENT_SECRET="client secret"
client =

Proxy Support

You can specify a http proxy using the :proxy_uri option, as follows:

client = :username => 'foo',
  :password       => 'bar',
  :security_token => 'security token',
  :client_id      => 'client_id',
  :client_secret  => 'client_secret',
  :proxy_uri      => ''

This paramter also will accept 'http://[email protected]' or using the environemnt variable PROXY_URI.

Sandbox Orgs

You can connect to sandbox orgs by specifying a host. The default host is '':

client = :host => ''

The host can also be set with the environment variable SALESFORCE_HOST.

Global configuration

You can set any of the options passed into globally:

Restforce.configure do |config|
  config.client_id     = 'foo'
  config.client_secret = 'bar'

Bang! methods

All the CRUD methods (create, update, upsert, destroy) have equivalent methods with a ! at the end (create!, update!, upsert!, destroy!), which can be used if you need to do some custom error handling. The bang methods will raise exceptions, while the non-bang methods will return false in the event that an exception is raised. This works similarly to ActiveRecord.


accounts = client.query("select Id, Something__c from Account where Id = 'someid'")
# => #<Restforce::Collection >

account = accounts.first
# => #<Restforce::SObject >

# => 'Account'

# => "someid"

account.Name = 'Foobar'
# => true

# => true


client.find('Account', '001D000000INjVe')
# => #<Restforce::SObject Id="001D000000INjVe" Name="Test" LastModifiedBy="005G0000002f8FHIAY" ... >

client.find('Account', '1234', 'Some_External_Id_Field__c')
# => #<Restforce::SObject Id="001D000000INjVe" Name="Test" LastModifiedBy="005G0000002f8FHIAY" ... >

select'Account', '001D000000INjVe', ["Id"])
# => {"attributes" : {"type" : "Account","url" : "/services/data/v20.0/sobjects/Account/001D000000INjVe"},
#   "Id" : "001D000000INjVe"}'Account', '001D000000INjVe', ["Id"], 'Some_External_Id_Field__c')
# => {"attributes" : {"type" : "Account","url" : "/services/data/v20.0/sobjects/Account/Some_External_Id_Field__c/001D000000INjVe"},
#   "Id" : "003F000000BGIn3"}


# Find all occurrences of 'bar''FIND {bar}')
# => #<Restforce::Collection >

# Find accounts match the term 'genepoint' and return the Name field'FIND {genepoint} RETURNING Account (Name)').map(&:Name)
# => ['GenePoint']


# Add a new account
client.create('Account', Name: 'Foobar Inc.')
# => '0016000000MRatd'


# Update the Account with Id '0016000000MRatd'
client.update('Account', Id: '0016000000MRatd', Name: 'Whizbang Corp')
# => true


# Update the record with external ID of 12
client.upsert('Account', 'External__c', External__c: 12, Name: 'Foobar')


# Delete the Account with Id '0016000000MRatd'
client.destroy('Account', '0016000000MRatd')
# => true


# get the global describe for all sobjects
# => { ... }

# get the describe for the Account object
# => { ... }


# get layouts for an sobject type
# => { ... }

# get the details for a specific layout
client.describe_layouts('Account', '012E0000000RHEp')
# => { ... }


client.picklist_values('Account', 'Type')
# => [#<Restforce::Mash label="Prospect" value="Prospect">]

# Given a custom object named Automobile__c with picklist fields
# Model__c and Make__c, where Model__c depends on the value of
# Make__c.
client.picklist_values('Automobile__c', 'Model__c', :valid_for => 'Honda')
# => [#<Restforce::Mash label="Civic" value="Civic">, ... ]


# get info about the logged-in user
# => #<Restforce::Mash active=true display_name="Chatty Sassy" email="[email protected]" ... >


Performs an authentication and returns the response. In general, calling this directly shouldn't be required, since the client will handle authentication for you automatically. This should only be used if you want to force an authentication before using the streaming api, or you want to get some information about the user.

response = client.authenticate!
# => #<Restforce::Mash access_token="..." id="" instance_url="" issued_at="1348465359751" scope="api refresh_token" signature="3fW0pC/TEY2cjK5FCBFOZdjRtCfAuEbK1U74H/eF+Ho=">

# Get the user information
info = client.get(
# => '005E0000001eM4LIAU'

File Uploads

Using the new Blob Data api feature (500mb limit):

client.create 'Document', FolderId: '00lE0000000FJ6H',
  Description: 'Document test',
  Name: 'My image',
  Body:'image.jpg', __FILE__), 'image/jpeg'))

Using base64 encoded data (37.5mb limit):

client.create 'Document', FolderId: '00lE0000000FJ6H',
  Description: 'Document test',
  Name: 'My image',
  Body: Base64::encode64('image.jpg'))

_See also: Inserting or updating blob data_

Downloading Attachments

Restforce also makes it incredibly easy to download Attachments:

attachment = client.query('select Id, Name, Body from Attachment').first, 'wb') { |f| f.write(attachment.Body) }

Custom Apex REST endpoints

You can use Restforce to interact with your custom REST endpoints, by using .get, .put, .patch, .post, and .delete.

For example, if you had the following Apex REST endpoint on Salesforce:

global class RESTCaseController {
  global static List<Case> getOpenCases() {
    String companyName = RestContext.request.params.get('company');
    Account company = [ Select ID, Name, Email__c, BillingState from Account where Name = :companyName];

    List<Case> cases = [SELECT Id, Subject, Status, OwnerId, Owner.Name from Case WHERE AccountId = :company.Id];
    return cases;

Then you could query the cases using Restforce:

client.get '/services/apexrest/FieldCase', :company => 'GenePoint'
# => #<Restforce::Collection ...>


Restforce supports the Streaming API, and makes implementing pub/sub with Salesforce a trivial task:

# Restforce uses faye as the underlying implementation for CometD.
require 'faye'

# Initialize a client with your username/password/oauth token/etc.
client = :username => 'foo',
  :password       => 'bar',
  :security_token => 'security token'
  :client_id      => 'client_id',
  :client_secret  => 'client_secret'

# Create a PushTopic for subscribing to Account changes.
client.create! 'PushTopic', {
  ApiVersion: '23.0',
  Name: 'AllAccounts',
  Description: 'All account records',
  NotifyForOperations: 'All',
  NotifyForFields: 'All',
  Query: "select Id from Account"
} {
  # Subscribe to the PushTopic.
  client.subscribe 'AllAccounts' do |message|
    puts message.inspect

Boom, you're now receiving push notifications when Accounts are created/updated.

_See also: Streaming API docs_


The gem supports easy caching of GET requests (e.g. queries):

# rails example:
client = cache: Rails.cache

# or
Restforce.configure do |config|
  config.cache = Rails.cache

If you enable caching, you can disable caching on a per-request basis by using .without_caching:

client.without_caching do
  client.query('select Id from Account')


You can easily inspect what Restforce is sending/receiving by setting Restforce.log = true.

Restforce.log = true
client ='select Id, Name from Account')

Another awesome feature about restforce is that, because it is based on Faraday, you can insert your own middleware. For example, if you were using Restforce in a rails app, you can setup custom reporting to Librato using ActiveSupport::Notifications:

client = do |builder|
  builder.insert_after Restforce::Middleware::InstanceURL,
    FaradayMiddleware::Instrumentation, name: 'request.salesforce'

# config/initializers/notifications.rb
ActiveSupport::Notifications.subscribe('request.salesforce') do |*args|
  event =*args)
  Librato.increment ''
  Librato.timing 'api.salesforce.request.time', event.duration
end Canvas

You can use Restforce to decode signed requests from Salesforce. See the example app.

Tooling API

To use the Tooling API, call Restforce.tooling instead of

client = Restforce.tooling(...)


If you need a full Active Record experience, may be you can use ActiveForce that wraps Restforce and adds Associations, Query Building (like AREL), Validations and Callbacks.


  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Related Repositories



Ruby client for the and Chatter APIs ...



A very simple REST API client for Python ...



Salesforce SOAP API wrapper based on Savon ...



Demo AngularJS application that connects to using Ruby on Rails. ...



A very simple REST API client for Python ...

Top Contributors

ejholmes bramswenson nahiluhmot chulkilee zenchild wazoo eloyesp daveespo wasabhi lukesutton Aupajo kidd ryanbrainard Charizard cobraextreme


-   v1.5.0 zip tar
-   v1.4.3 zip tar
-   v1.4.2 zip tar
-   v1.4.1 zip tar
-   v1.4.0 zip tar
-   v1.3.0 zip tar
-   v1.2.0 zip tar
-   v1.1.0 zip tar
-   v1.0.6 zip tar
-   v1.0.5 zip tar
-   v1.0.4 zip tar
-   v1.0.3 zip tar
-   v1.0.2 zip tar
-   v1.0.1 zip tar
-   v1.0.0 zip tar
-   v0.1.10 zip tar
-   v0.1.9 zip tar
-   0.1.8 zip tar
-   0.1.7 zip tar
-   0.1.6 zip tar
-   0.1.5 zip tar
-   0.1.4 zip tar
-   0.1.3 zip tar
-   0.1.2 zip tar
-   0.1.1 zip tar
-   0.1.0 zip tar
-   0.0.8 zip tar
-   0.0.7 zip tar
-   0.0.6 zip tar
-   0.0.2 zip tar