NAV
shell ruby

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>&amp;client_secret=<same as above>&amp;redirect_uri=<thing from above>&amp;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>
    }
  1. Get permission to access Avvo’s API.
  2. 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.
  3. 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.
  4. This generates a link to sign in and an access_token is sent along with the redirect.
  5. Capture the access_token sent in the redirect.
  6. 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.

  1. Get permission to access Avvo’s API.
  2. From OAuth Authentication section, generate a OAuth token. This is required.
  3. 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.
  4. 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_ids, 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.