User
- The FreshBooks account, whose information we are trying to access via OAuthConsumer
- The FreshBooks account, who we authorize to access the user's informationConsumer key
- The consumer's subdomain,consumer_key.freshbooks.com
Consumer Secret
- The consumer's secret, that we will use to make OAuth requests.Request Token
- A value used by the consumer to obtain authorization and an access token from the user.Access Token
- A value used by the consumer to access the user's information.Access Token Secret
- A secret used by the consumer to establish ownership of a given Token.Callback URL
- URL you want the user to be redirected to, after the user authorization step.Nonce
- A nonce is a random string, uniquely generated for each request.Timestamp
- The current number of seconds since January 1, 1970 00:00:00 GMT.
- On your FreshBooks account, go to "My Account", then "FreshBooks API".
- Enable OAuth under the "OAuth Developer Access" section:
- Fill out the authorization form:
- Once you've gained access, you'll see your
Consumer Secret
.
This can be any FreshBooks account, even the consumer account.
- Make sure the following parameters are set on the Authorization header:
- OAuth realm=""
- oauth_version="1.0"
- oauth_consumer_key="<
CONSUMER_SUBDOMAIN>
" - oauth_timestamp="
<TIMESTAMP>
" - oauth_nonce="
<NONCE>
" - oauth_signature_method="PLAINTEXT"
- oauth_signature="
<CONSUMER SECRET>%2526
" - oauth_callback="
<CALLBACK URL>
"
- Make a POST to the following URL:
https://<USER SUBDOMAIN>.freshbooks.com/oauth/oauth_request.php
- You'll receive a response from the server with both an
oauth_token
and anoauth_token_secret
. Make sure you store those two values somewhere.
- The
user
has to now authorize theconsumer
to access their data, so theuser
has to open up the following url in a browser:https://<USER SUBDOMAIN>.freshbooks.com/oauth/oauth_authorize.php?oauth_token=<oauth_token>
- If the oauth_token is valid, the
user
will be asked to sign in and allow access. - You'll receive a verifier, which you should store.
- If a
<CALLBACK_URL>
was defined, theuser
will be redirected to the URL with the verifier as a query string:<CALLBACK_URL?verifier=<VERIFIER_VALUE>
- If a
<CALLBACK_URL>
was not defined, the<VERIFIER_VALUE>
will be displayed on the page.
- You'll be making another post now, to get your Access tokens. Make sure you swap out the right values on the Authorization header:
- OAuth realm=""
- oauth_version="1.0"
- oauth_consumer_key="
<CONSUMER_SUBDOMAIN>
" - oauth_timestamp="
<TIMESTAMP>
" - oauth_nonce="
<NONCE>
" - oauth_signature_method="PLAINTEXT"
- oauth_signature="
<CONSUMER SECRET>%2526
" - oauth_token="
<OAUTH_TOKEN>
" - oauth_verifier="
<VERIFIER_VALUE>
"
- Make a POST to the following URL:
https://<USER SUBDOMAIN>.freshbooks.com/oauth/oauth_access.php
- You'll finally receive a response from the server with new
oauth_token
and anoauth_token_secret
values. Make sure you store those two values somewhere.
- You're now able to make API calls with OAuth! Make sure you swap out the right values in the Authorization header:
- OAuth realm=""
- oauth_version="1.0"
- oauth_consumer_key="
<CONSUMER_SUBDOMAIN>
" - oauth_timestamp="
<TIMESTAMP>
" - oauth_nonce="
<NONCE>
" - oauth_signature_method="PLAINTEXT"
- oauth_signature="
<CONSUMER_SECRET>%2526<OAUTH_TOKEN_SECRET>
" - oauth_token="
<OAUTH_TOKEN>
"
- Make a POST to the following URL:
https://<USER SUBDOMAIN>.freshbooks.com/api/2.1/xml-in
Here's an example using purely curl commands. Today's consumer will be darthvader.freshbooks.com
, who will be trying to access rebels.freshbooks.com
's data.
- Preparing our authorization header
- oauth_consumer_key:
darthvader
- oauth_timestamp:
1368630669
- oauth_nonce:
UU7gRl0HDdt
- oauth_signature:
G6A9YrCrdizGDdtyWU9FgrAP795KL5baj%2526
- Posting to
https://rebels.freshbooks.com/oauth/oauth_request.php
with the following values in our Authorization header:
$ curl -k -H 'Authorization: OAuth realm="",oauth_version="1.0",oauth_consumer_key="darthvader",oauth_timestamp="1368630669",oauth_nonce="UU7gRl0HDdt",oauth_signature_method="PLAINTEXT",oauth_signature="G6A9YrCrdizGDdtyWU9FgrAP795KL5baj%2526",oauth_callback=""' -X POST https://rebels.freshbooks.com/oauth/oauth_request.php
- Which gives us the following response:
oauth_token=ezRLfnwqT4euejh3eFZr5w5UsGmcTqp2&oauth_token_secret=SSF4aRtvFEEX9wBWqebrfpskufHrLtU7V&oauth_callback_confirmed=true
-
Using the obtained oauth_token, I open up the following URL in my browser:
https://rebels.freshbooks.com/oauth_oauth_authorize.php?oauth_token=ezRLfnwqT4euejh3eFZr5w5UsGmcTqp2
-
Since I didn't provide a callback_url, the verifier was right on the page for me:
fsVZcfYq8vv7pJzKfzk96cswXuGBpKiRu
- Preparing our authorization header
- oauth_consumer_key:
darthvader
- oauth_token:
ezRLfnwqT4euejh3eFZr5w5UsGmcTqp2
- oauth_timestamp:
1368630857
- oauth_nonce:
bDu0qrocMxD
- oauth_signature:
G6A9YrCrdizGDdtyWU9FgrAP795KL5baj%2526
- oauth_verifier:
fsVZcfYq8vv7pJzKfzk96cswXuGBpKiRu
- Posting to
https://rebels.freshbooks.com/oauth/oauth_access.php
$ curl -k -H 'Authorization: OAuth realm="",oauth_version="1.0",oauth_consumer_key="darthvader",oauth_token="ezRLfnwqT4euejh3eFZr5w5UsGmcTqp2",oauth_timestamp="1368630857",oauth_nonce="bDu0qrocMxD",oauth_signature_method="PLAINTEXT",oauth_signature="G6A9YrCrdizGDdtyWU9FgrAP795KL5baj%2526",oauth_verifier="fsVZcfYq8vv7pJzKfzk96cswXuGBpKiRu"' -X POST https://rebels.freshbooks.com/oauth/oauth_access.php
- Which gives us the following response:
oauth_token=KsT3w4xPpYLd3dTEsRDv7RvvBGy8X36Mv&oauth_token_secret=MnfWWC4ZHiuEe52v7feuBH9FdfRce9rxC
- Preparing our authorization header
- oauth_consumer_key:
darthvader
- oauth_token:
KsT3w4xPpYLd3dTEsRDv7RvvBGy8X36Mv
- oauth_timestamp:
1368631017
- oauth_nonce:
ddtCiqS5nlZ
- oauth_signature:
G6A9YrCrdizGDdtyWU9FgrAP795KL5baj%2526MnfWWC4ZHiuEe52v7feuBH9FdfRce9rxC
- Making a post to
https://rebels.freshbooks.com/api/2.1/xml-in
:
$ curl -k -H 'Authorization: OAuth realm="",oauth_version="1.0",oauth_consumer_key="darthvader",oauth_token="KsT3w4xPpYLd3dTEsRDv7RvvBGy8X36Mv",oauth_timestamp="1368631017",oauth_nonce="ddtCiqS5nlZ",oauth_signature_method="PLAINTEXT",oauth_signature="G6A9YrCrdizGDdtyWU9FgrAP795KL5baj%2526MnfWWC4ZHiuEe52v7feuBH9FdfRce9rxC"' -X POST https://rebels.freshbooks.com/api/2.1/xml-in -d '<request method="invoice.list" />'
- Which gives us the following response:
<?xml version="1.0" encoding="utf-8"?>
<response xmlns="http://www.freshbooks.com/api/" status="ok">
<invoices page="1" per_page="25" pages="1" total="1">
<invoice>
<invoice_id>00000248946</invoice_id>
<organization>Princess Leia</organization>
<first_name>Leia</first_name>
<last_name>Organa</last_name>
<lines>
<line>
<line_id>1</line_id>
<name>Death Star Plans</name>
<unit_cost>10000000000000000.00</unit_cost>
<quantity>1</quantity>
<amount>10000000000000000.00</amount>
<type>Item</type>
</line>
</lines>
</invoice>
</invoices>
</response>
Hi Anton
I find your article more interesting.
My questions are:
1.) Under the Find a FreshBooks account(above), when I created my Account and I have setup an Accountant and Staff (under People Tab), Do they qualify as a FreshBook Account?
I think I have the same case for Robert J you'd answered from this link: https://groups.google.com/forum/#!topic/freshbooks-api/SOFTZJSb9DM
2.) I was able to successfully simulate all your steps except for the last one: Accessing User Data
I am using google's postman as a debugger... I'm trying to pull the client's list (...e.g.) I am getting
an (20010) Authentication failed error.
Your answer is very much appreciated.
Thank you
Regards;
Alfred