Avvo API
Getting Access
API Endpoint
https://api.avvo.com/api/4
To use the API, you must create an Avvo account. Afterwards, click here to get set up.
We format our responses in JSON according to the Json API standard.
Detailed documentation for each possible action, including the URL endpoint and required parameters, are available below. All Avvo API responses will be returned in JSON, which is human-readable. JSON parsers are also available for nearly every language. Example responses are shown on the API detail pages.
Format
We format our responses in JSON according to the Json API standard.
Authentication
This API support Oauth2 authentication:
OAuth2
OAuth step 3.
curl -X POST --data 'redirect_uri=<the direct URI from my app>&client_id=<the avvo app client id>&client_secret=<the avvo app secret I only got to see once when I first registered the app>&response_type=code_and_token' https://api.avvo.com/api/2/oauth2/authorize
OAuth steps 4 and 5.
This does not redirect you, but it will give you the redirect URL. You can paste that in a browser. Then you can see the access_token in the URL after you authorize the app.
Ex: https://www.avvo.com/oauth2/sessions/new?client_id=<same as above>&client_secret=<same as above>&redirect_uri=<thing from above>&response_type=code_and_token
OAuth step 6.
curl https://api.avvo.com/api/4/lawyers.json \
-H "Authorization: Bearer abd90df5f27a7b170cd775abf89d632b350b7c1c9d53e08b340cd9832ce52c2c"
require "oauth2"
callback_url = "https://www.yoursite/oauth2/callback"
client = OAuth2::Client.new(<client_id>, <client_secret>, site: "https://api.avvo.com", authorize_url: ”/api/2/oauth2/authorize”, token_url: “/api/2/oauth2/authorize”)
client.auth_code.authorize_url(redirect_uri: callback_url)
token = client.auth_code.get_token("authorization_code_value", redirect_uri: callback_url,
headers: {"Authorization" => "Basic some_password"})
response = token.get('api/4/lawyers.json', params: { id: 123 })
response.class.name
# => OAuth2::Response
OAuth2 is recommended when you’re creating an application for others on top of Avvo’s platform. This authentication provides a secure and easy to use authentication flow for users.
OAuth2 requests must be authenticated with a valid access token passed as bearer token. To use the bearer token, construct a normal HTTPS request and include an Authorization header with the value of Bearer. Signing is not required.
Read more about OAuth2 authentication.
Obtaining an OAuth Access Token
{ response_type: code_and_token,
client_id: <client_id>,
client_secret: <client_secret>
redirect_uri: <redirect_url used for registration>
}
- Get permission to access Avvo’s API.
- Login to Avvo.com and visit https://www.avvo.com/oauth2/apps. Create a new app. For the redirect URL field, enter a URL for your server, or you can use Postman to test this out, in which case you’d use https://www.getpostman.com/oauth2/callback. If you use Postman, Auth URL and Access token URL are both https://api.avvo.com/api/2/oauth2/authorize and Client ID and Client Secret are from the app you are creating now, available when you save this form.
- Post a call to
https://api.avvo.com/api/2/oauth2/authorize
with your id and secret to obtain an auth code and access token. See example curl command, or use Postman while testing this authorization. - This generates a link to sign in and an access_token is sent along with the redirect.
- Capture the access_token sent in the redirect.
- Add this to the Bearer Authorization header of each request.
JWT Authentication
JSON Web Token (JWT) is an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret or a public/private key pair using RSA or ECDSA. Read more about JWT.
Obtaining a JWT [GET]
# Obtaining a JWT.
curl --location --request GET 'api.avvo.com/api/5/jwt_access/lawyer_token/<lawyer id>' \
--header 'Authorization: Bearer <oauth token>'
# Obtaining a JWT.
require "uri"
require "net/http"
url = URI("api.localtest.me/api/5/jwt_access/lawyer_token/#{@lawyer_id}")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer #{@oauth_token}"
response = http.request(request)
puts response.read_body
Example response
{
"jwt": "eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7Imxhd3llciI6eyJpZCI6NDU4MDQwNCwibmFtZSI6IkVkd2FyZCBDLiBPa3d1ZXplIiwidXNlcl9pZCI6MjI5MzQxM30sImFwaV91c2VyIjp7InVzZXJfaWQiOjY5MDcyNTYsImVtYWlsX2FkZHJlc3MiOiJjaGF0bWV0ZXJAZGVtby5jb20iLCJuYW1lIjoiQ2hhdG1ldGVyLXRlc3QiLCJwZXJtaXNzaW9ucyI6WyJtYW5hZ2Vfb2F1dGgyX2FwcCIsInNvbGljaXRvcl9hcGlfcmVhZCIsInZlcmlmeV9hcGlfcmVhZCIsInJldmlld19tYW5hZ2VyX3JlYWQiLCJyZXZpZXdfbWFuYWdlcl93cml0ZSJdfX0sImlzcyI6IkF2dm8uY29tIC0gTGVnYWwuIEVhc2llci4iLCJleHAiOjE2MjU4NzAzMTN9.WJ-2DIFgGi-fbtLkQlp98B7JcBh-Tq_WOsmwzn5KtDc",
"meta": {
"message": "Token Generated",
"status": 200
}
}
A lawyer specific JWT is issued by the JWT generator endpoint. All the JWT authenticated endpoints responses will be scoped to this lawyer. The JWT generator is protected by OAuth authentication. OAuth access token must be provided as a bearer token for this endpoint.
- Get permission to access Avvo’s API.
- From OAuth Authentication section, generate a OAuth token. This is required.
- Post a call to https://api.avvo.com/api/5/jwt_access/lawyer_token/:lawyer_id and replace the :lawyer_id with the desired lawyer.
- Response will include the JWT desired. The JWT is valid for 20 mins.
URL
https://api.avvo.com/api/5/jwt_access/lawyer_token/:lawyer_id
Lawyers
Get single, bulk, or search for Avvo lawyers.
Example response
{
"lawyers": [
{
"id": 1002479,
"firstname": "Aaron",
"lastname": "Kiviat",
"middlename": "S",
"suffix": null,
"aliases": [ ],
"avvo_pro": true,
"avvo_rating": 10.0,
"client_review_count": 25,
"client_review_score": 5.0,
"headshot_url": "http://placekitten.com/400/400",
"licensed_since": 2004,
"bio": "Lorem ipsum dolores sut amet.",
"lawyer_specialties": [
{
"name": "DUI & DWI",
"percent": 25
},
],
"browse_links": [
{
"type": "profile",
"url": "http://www.avvo.com/attorneys/28895.html"
},
]
},
]
"meta":{
"status": 200,
"current_page": 1,
"per_page": 10,
"total_pages": 227995,
"total_entries": 2279945
}
}
Fields
Field | Description |
---|---|
id | Id of the lawyer. This is the primary record key |
firstname | The lawyer’s first name |
middlename | The lawyer’s middle name |
lastname | The lawyer’s last name |
suffix | Name suffix, e.g. Esq. |
aliases | Other names the lawyers have listed, e.g. Bubba |
avvo_pro | Whether the lawyer is an Avvo Pro |
avvo_rating | The lawyer’s Avvo rating |
client_review_count | Number of client reviews |
client_review_score | The average rating based on client reviews |
headshot_url | The URL to the lawyer’s headshot image |
licensed_since | The year in which the lawyer was licensed |
bio | The lawyer’s bio. |
lawyer_specialties | The lawyer’s specialties. Array of {"name": "", "percent":""} JSON blobs |
browse_links | Lawyer links. Can be of type “profile” and “contact”. Array of {"type":"", "url":""} JSON blobs |
Index [GET]
Look up multiple lawyers by id
URL
https://api.avvo.com/api/4/lawyers.json
Params
Param | Value |
---|---|
id | Primary key of the layer |
Array of IDs, in the standard Rails format:
https://api.avvo.com/api/4/lawyers.json?id[]=1&id[]=2
Show [GET]
Look up a single lawyer.
URL
https://api.avvo.com/api/4/lawyers/:id.json
Param | Value |
---|---|
id | Primary key of the lawyer |
Search [GET]
Natural text search for lawyers in location by name or specialty
URL
https://api.avvo.com/api/4/lawyers/search.json
Params
All of the params are optional
Param | Description | Values |
---|---|---|
q | Query string | Plain English query string, e.g. “DUI” or “Mark Britton” |
loc | Location string. Can be replaced with lat long values. | Plain English location string, e.g. “Seattle, wa” |
lat | Latitude value | Floating point number |
long | Longitude value | Floating point number |
radius | Search radius. Works for both lat long and loc searches |
Integer |
has_reviews | Filters lawyers who have reviews | true/false |
avvo_rating | Sort by Avvo rating | not required |
client_rating | Sort by average value of client ratings | not required |
number_of_reviews | Sort by number of client reviews | not required |
per_page | number of lawyers per page | not required |
page | page number for query | not required |
Lawyer Address
Find the addresses for a given lawyer
Example response
{
"lawyer_addresses": [
{
"id": 1002779,
"lawyer_id": 1002479,
"line1": "123 Sesame Street",
"line2": null,
"city": "New York",
"state_code": "NY",
"postal_code": "10001"
}
],
"meta": {
"status": 200,
"current_page": 1,
"per_page": 10,
"total_pages": 1,
"total_entries": 1
}
}
Fields
Field | Description |
---|---|
id | Id of the lawyer address. This is the primary record key |
lawyer_id | Id of the associated lawyer object |
line1 | The first line of the address |
line2 | The second line of the address |
city | The city of the address |
state_code | State abbreviation |
postal_code | The postal code of the address |
Index [GET]
Look up multiple legal services by id
URL
https://api.avvo.com/api/4/lawyer_addresses.json
Params
Param | Value |
---|---|
lawyer_id | The primary id of the lawyer the addresses belong to |
lawyer_ids | A comma-separated string of lawyer_ids for querying multiple lawyer’s addresses in one API call |
Specialties
Get single, bulk, or search for specialties that Avvo has listed.
Example response
{
"specialties": [
{
"id": 56,
"name": "DUI & DWI",
"description": "If you are suspected of driving while under the influence of alcohol or drugs, you may be arrested for DUI (driving under the influence). Depending on the state, the specific crime is also called DWI (driving while intoxicated), OUI (operating under the influence), or OWI (operating while intoxicated). A DUI conviction has serious consequences (for example, losing your driving privileges); but an experienced DUI attorney can often get the charges dropped or reduced, or may be able to negotiate lesser penalties depending on your circumstances and your past history."
}
],
"meta":
{
"status": 200,
"current_page": 1,
"per_page": 30,
"total_pages": 1,
"total_entries": 2
}
}
Fields
Field | Description |
---|---|
id | Primary key |
name | Spcialty name |
description | Brief description of the specialty |
Index [GET]
Get multiple specialties
URL
https://api.avvo.com/api/4/specialties.json
Params
Param | Value |
---|---|
id | Primary key of the specialty |
Array of IDs, in the standard Rails format:
https://api.avvo.com/api/4/specialties.json?id[]=1&id[]=2
Show [GET]
Get single specialty by id
URL
https://api.avvo.com/api/4/specialties/:id.json
Params
Param | Value |
---|---|
id | Primary key of the specialty |
Search [GET]
Find a specialty by a natural language string.
URL
https://api.avvo.com/api/4/specialties/search.json
Params
Param | Description | Values |
---|---|---|
q | Query string | Plain English query string, e.g. “Dui” |
Reviews
Lawyer reviews. These are the reviews that are visible for lawyers on the website.
Example response
{
"reviews": [
{
"lawyer_id": 28995,
"title": "Great GC when at Expedia",
"body": "I worked with Mark for 4 years while we were at Expedia together. He was GC for most of this time. I found Mark to be extremely sharp, able to integrate business and legal thinking in such a way as to deliver answers to problems that appropriately balanced risks and opportunities, something that I think is vital in a GC yet can be hard to find."
}
],
"meta":
{
"status": 200,
"current_page": 1,
"per_page": 10,
"total_pages": 1,
"total_entries": 1
}
}
Fields
Field | Description |
---|---|
lawyer_id | The lawyer’s id |
rating | The client’s rating of the lawyer (0 - 5) |
title | The title of the review |
body | The body text of the review |
Index [GET]
Get reviews for a specific lawyer
URL
https://api.avvo.com/api/4/reviews.json
Params
Param | Value |
---|---|
lawyer_id | primary key of lawyer whose reviews you need to get |
Array of lawyer_id
s, in the standard Rails format:
https://api.avvo.com/api/4/reviews.json?lawyer_id[]=1&lawyer_id[]=2
Index (JWT) [GET]
# Fetching reviews.
curl --location --request GET 'api.avvo.com/api/5/reviews?page=1&per_page=2' \
--header 'Authorization: Bearer <jwt>'
require "uri"
require "net/http"
url = URI("http://api.avvo.com/api/5/reviews?page=1&per_page=2")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer <jwt>"
response = http.request(request)
puts response.read_body
Get reviews for a specific lawyer. Lawyer is specified in the JWT
URL
https://api.avvo.com/api/5/reviews
Example response
{
"reviews": [
{
"id": 1234567,
"lawyer_id": 1234567,
"lawyer_prefix": null,
"lawyer_firstname": "John",
"lawyer_middlename": "F.",
"lawyer_lastname": "Doe",
"lawyer_suffix": null,
"rating": 4,
"title": "Ruler of lawyers",
"body": "The best criminal lawyers in texas.",
"comments": [
{
"id": 1234567,
"body": "Thanks for the very kind words.",
"created_at": "2017-02-10T18:45:07.000-08:00",
"updated_at": "2017-02-10T18:45:07.000-08:00"
}
],
"review_type": "HIRED",
"created_at": 1461042905
},
...
],
"meta": {
"status": 200, "current_page": 1,
"per_page": 20, "total_pages": 10,
"total_entries": 192
}
}
Params
Param | Value |
---|---|
page | Page number for query |
per_page | Number of reviews per page |
Authorization
Type | Value |
---|---|
Bearer Token | JWT |
Show (JWT) [GET]
# Fetching specific review.
curl --location --request GET 'api.avvo.com/api/5/reviews/:review_id' \
--header 'Authorization: Bearer <jwt>'
require "uri"
require "net/http"
url = URI("http://api.avvo.com/api/5/reviews/:review_id")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Get.new(url)
request["Authorization"] = "Bearer <jwt>"
response = http.request(request)
puts response.read_body
Get a specific review by its ID. Review must belong to the lawyer specified in the JWT
URL
https://api.avvo.com/api/5/reviews/:review_id
Example response
{
"reviews": [
{
"id":1234567,
"lawyer_id": 1234567,
"lawyer_prefix": null,
"lawyer_firstname": "John",
"lawyer_middlename": "F.",
"lawyer_lastname": "Doe",
"lawyer_suffix": null,
"rating": 4,
"title": "king of lawyers",
"body": "Thanks to the best criminal lawyers in texas. ",
"comments": [
{
"id": 1234567,
"body": "Thanks for the very kind words.",
"created_at": "2017-02-10T18:45:07.000-08:00",
"updated_at": "2017-02-10T18:45:07.000-08:00"
}
],
"review_type": "HIRED",
"created_at": 1461042905
}
],
"meta": { "status": 200 }
}
Params
Param | Value |
---|---|
page | Page number for query |
per_page | Number of reviews per page |
Authorization
Type | Value |
---|---|
Bearer Token | JWT |
Review Comments
Reviews comments. These are the comments that lawyer posts to the review.
Create (JWT) [POST]
# Create review comment.
curl --request POST 'api.avvo.com/api/5/reviews/:review_id/comments' \
--header 'Authorization: Bearer <jwt>' \
--header 'Content-Type: application/json' \
--data '{"body": "<comment_body>"}'
require "uri"
require "net/http"
url = URI("http://api.avvo.com/api/5/reviews/:review_id/comments")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Authorization"] = "Bearer <jwt>"
request["Content-Type"] = "application/json"
request.body = {body: "<Review Comment Body>"}.to_json
response = http.request(request)
puts response.read_body
Post a comment to a specific review with :review_id
on behalf of a lawyer. Lawyer is specified in the JWT. Currently only one comment is allowed per review.
URL
https://api.avvo.com/api/5/reviews/:review_id/comments
Example of a successful response
{
"review_comment_id": 2666174,
"meta": {
"status": 201,
"message": "review comment created"
}
}
Example of a failure response
{
"meta": {
"error": "param is missing or the value is empty: body",
"status": 422
}
}
URL Params
Param | Value |
---|---|
review_id | Id of the review to post the comment |
Request body
Param | Value |
---|---|
body | Body of the review comment |
Authorization
Type | Value |
---|---|
Bearer Token | JWT |
Update (JWT) [PUT]
# Update specific review comment body.
curl --request PUT 'api.avvo.com/api/5/reviews/comments/:review_comment_id' \
--header 'Authorization: Bearer <jwt>' \
--header 'Content-Type: application/json' \
--data '{"body": "<comment_body>"}'
require "uri"
require "net/http"
url = URI("http://api.avvo.com/api/5/reviews/comments/:review_comment_id")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Put.new(url)
request["Authorization"] = "Bearer <jwt>"
request["Content-Type"] = "application/json"
request.body = {body: "<New Review Comment Body>"}.to_json
response = http.request(request)
puts response.read_body
Update a specific review by its ID. Review comment must belong to the lawyer specified in the JWT.
URL
https://api.avvo.com/api/5/reviews/comment/:review_comment_id
Example of a successful response
{
"meta": {
"status": 200,
"message": "review comment updated"
}
}
Example of a successful response
{
"meta": {
"error": "param is missing or the value is empty: body",
"status": 422
}
}
Request body
Param | Value |
---|---|
body | Body of the review comment |
Authorization
Type | Value |
---|---|
Bearer Token | JWT |
Errors
The Avvo API uses the following error codes:
Error Code | Meaning |
---|---|
301 | Moved permanently – This and all future requests should be directed |
400 | Bad Request – Your request is bad |
401 | Unauthorized – Your API key is wrong |
403 | Forbidden – You’re not authorized to view this file |
404 | Not Found – Resource not found |
500 | Internal Server Error – We had a problem with our server. Try again later. |
503 | Service Unavailable – We’re temporarially offline for maintenance. Please try again later. |