NAV Navbar
http shell r ruby
  • Introduction
  • Base URL
  • Fishbase vs. Sealifebase
  • Database versions
  • HTTP methods
  • Response Codes
  • Response headers
  • Response bodies
  • Media Types
  • Pagination
  • Authentication
  • Parameters
  • Routes
  • API Clients
  • Introduction

    Welcome to the Fishbase API! You can use our API to access Fishbase data.

    We have examples for Shell (using curl and jq), R, and Ruby! You can view code examples in the dark area to the right (or below if on mobile), and you can switch the programming language of the examples with the tabs in the top right.

    Base URL

    Fishbase vs. Sealifebase

    In addition to Fishbase, we also server Sealifebase data from this API.

    To use Sealifebase API insted of Fishbase, add /sealifebase to the base URL, like:

    Everything described below should work the same for both Fishbase and Sealife base APIs.

    Database versions

    The Fishbase API supports multiple different versions of the underlying database.

    You can request a different database version with a HTTP header like Accept: application/vnd.ropensci.v3+json

    Where v3 represents "version 3". Likewise, v2 is "version 2", and v1 is "version 1". These versions correspond to specific dates associated with different database versions. The current versions for Fishbase are:

    The date format YYYYMM is four digits for year, then two digits for month, with no spaces/characters between them.

    By default, we return the latest date version.

    See the /versions route for description of the different versions and their names.

    In the R client rfishbase the database version will be controlled by a parameter or option/env var, so users won't have to pass headers themselves.

    HTTP methods

    This is essentially a read only API. That is, we only allow GET (and HEAD) requests on this API.

    Requests of all other types will be rejected with appropriate 405 code, including POST, PUT, COPY, HEAD, DELETE, etc.

    Response Codes

    400 responses will look something like

    HTTP/1.1 400 Bad Request
    Cache-Control: public, must-revalidate, max-age=60
    Connection: close
    Content-Length: 61
    Content-Type: application/json
    Date: Thu, 26 Feb 2015 23:27:57 GMT
    Server: nginx/1.7.9
    Status: 400 Bad Request
    X-Content-Type-Options: nosniff
        "error": "invalid request",
        "message": "maximum limit is 5000"

    404 responses will look something like

    HTTP/1.1 404 Not Found
    Cache-Control: public, must-revalidate, max-age=60
    Connection: close
    Content-Length: 27
    Content-Type: application/json
    Date: Thu, 26 Feb 2015 23:27:16 GMT
    Server: nginx/1.7.9
    Status: 404 Not Found
    X-Cascade: pass
    X-Content-Type-Options: nosniff
        "error": "route not found"

    405 responses will look something like (with an empty body)

    HTTP/1.1 405 Method Not Allowed
    Access-Control-Allow-Methods: HEAD, GET
    Access-Control-Allow-Origin: *
    Cache-Control: public, must-revalidate, max-age=60
    Connection: close
    Content-Length: 0
    Content-Type: application/json; charset=utf8
    Date: Mon, 27 Jul 2015 20:48:27 GMT
    Server: nginx/1.9.3
    Status: 405 Method Not Allowed
    X-Content-Type-Options: nosniff

    500 responses will look something like

    HTTP/1.1 500 Internal Server Error
    Cache-Control: public, must-revalidate, max-age=60
    Connection: close
    Content-Length: 24
    Content-Type: application/json
    Date: Thu, 26 Feb 2015 23:19:57 GMT
    Server: nginx/1.7.9
    Status: 500 Internal Server Error
    X-Content-Type-Options: nosniff
        "error": "server error"

    Occassionally you may get a MySQL error message in your error slot. Get in touch with us if that happens as that shouldn't be happening, and we'll need to fix something on our end.

    Response headers

    Response headers give the following noteable things:

    200 response header will look something like

    Access-Control-Allow-Methods: HEAD, GET
    Access-Control-Allow-Origin: *
    Cache-Control: public, must-revalidate, max-age=60
    Connection: close
    Content-Length: 10379
    Content-Type: application/json; charset=utf8
    Date: Mon, 09 Mar 2015 23:01:23 GMT
    Server: nginx/1.7.10
    Status: 200 OK
    X-Content-Type-Options: nosniff

    Response bodies

    Response bodies generally look like:

        "count": 1,
        "returned": 1,
        "data": [
            "AnaCat": "potamodromous",
            "AquacultureRef": 12108,
            "Aquarium": "never/rarely",
            "AquariumFishII": " ",
            "AquariumRef": null,
            "Author": "(Linnaeus, 1758)"
        "error": null

    Responses have 4 slots:

    Responses with errors also have the same 4 slots, but no data returned, and there should be an informative error message.

    Media Types

    We serve up only JSON in this API. All responses will have Content-Type: application/json; charset=utf8.


    The query parameters limit (default = 10) and offset (default = 0) can be used to toggle the number of results you get back and what record you start at. This doesn't apply to some routes, which don't accept any parameters (e.g., docs).

    The response body from the server will include data on records found in count and number returned in returned:

    Ideally, we'd put in a helpful links object - hopefully we'll get that done in the future.


    We don't require any. Cheers :)


    Common parameters

    Above parameters common to all routes except:

    In addition, these routes do not support limit or offset:

    Additional parameters

    Right now, any field that is returned from a route can also be queried on, except for the /taxa route, which only accepts species and genus in addition to the common parameters. All of the fields from each route are too long to list here - inspect data returned from a small data request, then change your query as desired.

    Right now, parameters that are not found are silently dropped. For example, if you query with /species?foo=bar in a query, and foo is not a field in species route, then the foo=bar part is ignored. We may in the future error when parameters are not found.



    GET [/]


    curl -L ""

    Redirects to


    GET [/heartbeat]

    Lists all the routes, and gives some indicaion of what can be passed to them.

    curl "" |  jq .
      "routes": [
    res <- rfishbase::heartbeat()
    jsonlite::fromJSON(httr::content(res, "text"))
     [1] "/docs/:table?"            "/heartbeat"               "/mysqlping"               "/listfields"
     [5] "/comnames?<params>"       "/country?<params>"
    require 'faraday'
    require 'multi_json'
    conn = '')
    res = conn.get 'heartbeat'

    The above command returns a Hash like:

    => {"routes"=>


    GET [/docs]

    Get brief description of each table in the Fishbase database.


    GET [/versions]

    Get Fishbase database versions.

    curl "" |  jq .
      "data": [
          "v1": {
            "name": "201505",
            "date_released": "2015-05-20"
          "v2": {
            "name": "201604",
            "date_released": "2016-04-28"
          "v3": {
            "name": "201703",
            "date_released": "2017-03-31"
      "error": null

    docs by table

    GET [/docs/{table}]

    Get all field names in a table. In the future, the returned data will include metadata on what each field means (understandable to a human), and what kind of data each field holds.


    GET [/comnames{?limit}{?offset}{?fields}]

    Search the common names table

    curl "" |  jq .
      "count": 319060,
      "returned": 1,
      "data": [
          "autoctr": 236404,
          "ComName": " ???????",
          "Transliteration": "Varimeen",
          "StockCode": 135,
          "SpecCode": 121,
          "C_Code": "356",
          "Language": "Telugu",
          "Script": "Telugu",
    common_names(species_list = "Bolbometopon muricatum")
    # A tibble: 64 x 6
                ComName SpecCode C_Code         Language        Genus   Species
                  <chr>    <int>  <chr>            <chr>        <chr>     <chr>
     1        Aliyakyak     5537    608          Visayan Bolbometopon muricatum
     2            Angke     5537    360 Bahasa Indonesia Bolbometopon muricatum
     3            Angke     5537    360             Bajo Bolbometopon muricatum
     4            Angke     5537    360            Malay Bolbometopon muricatum
     5            Angol     5537    608            Bikol Bolbometopon muricatum
     6            Bayan     5537    458            Malay Bolbometopon muricatum
     7    Bayan bonggol     5537    458            Malay Bolbometopon muricatum
     8         Berdebed     5537    585          Palauan Bolbometopon muricatum
     9            Boila     5537    090             Gela Bolbometopon muricatum
    10 Bulepapegøjefisk     5537    208           Danish Bolbometopon muricatum
    # ... with 54 more rows
    require 'faraday'
    require 'multi_json'
    conn = '')
    res = conn.get 'comnames', {"SpecCode": 5537}
    dat = MultiJson.load(res.body)
    dat['data'].collect{ |x| x['ComName']}
    => ["Aliyakyak",
     "Bayan bonggol",
     "Bumphead parrotfish"]


    GET [/countref{?limit}{?offset}{?fields}]

    Count ref

    curl "" |  jq .


    GET [/country{?limit}{?offset}{?fields}]

    Search the country table

    curl "" |  jq .


    GET [/diet{?limit}{?offset}{?fields}]

    Search the fish diet table

    curl "" |  jq .


    GET [/ecology{?limit}{?offset}{?fields}]

    Search the ecology table

    curl "" |  jq .


    GET [/ecosystem{?limit}{?offset}{?fields}]

    Search the ecosystem table

    curl "" |  jq .

    fao areas routes


    GET [/faoareas{?limit}{?offset}{?fields}]

    curl "" |  jq .
      "count": 60522,
      "returned": 1,
      "data": [
          "autoctr": 483,
          "AreaCode": 1,
          "SpecCode": 2,
          "StockCode": 1,
          "Status": "endemic",
          "Entered": 2,
          "DateEntered": "1990-10-19T00:00:00.000Z",
          "Modified": 675,
          "DateModified": "2011-02-11T17:16:45.000Z",
          "Expert": null,
          "DateChecked": null,
          "TS": null
      "error": null

    faoareas by id

    GET [/faoareas{id}]

    List faoareas by id

    curl "" |  jq .


    GET [/faoarref{?limit}{?offset}{?fields}]

    curl "" |  jq .

    faoarref by id

    GET [/faoarref{id}]

    List faoareas by id

    curl "" |  jq .


    GET [/fecundity{?limit}{?offset}{?fields}]

    Search the fecundity table

    curl "" |  jq .


    GET [/fooditems{?limit}{?offset}{?fields}]

    Search the fooditems table

    curl "" |  jq .
      "count": 53598,
      "returned": 1,
      "data": [
          "autoctr": 38,
          "StockCode": 1,
          "SpecCode": 2,
          "Locality": "Sudd swamps, River Nile.",
          "C_Code": "736",
          "FoodsRefNo": 6160,
          "FoodI": "detritus",
          "PreyStage": "n.a./others",
          "FoodII": "detritus",
          "FoodIII": "debris",
          "Commoness": 23,
          "CommonessII": "very common (21-50%)",
          "Foodgroup": "unidentified",
          "Foodname": "< 1 mm organic debris",
          "PreySpecCode": null,
          "PreySpecCodeSLB": null,
          "AlphaCode": null,
          "PreyTroph": null,
          "PreySeTroph": null,
          "TrophRefNo": null,
          "PredatorStage": "juv./adults",
          "Locality2": "Locality: Sudd swamps, River Nile; no. of fish examined=48; size=2.3-35.8 cm SL. Also Ref. 42341.",
          "Entered": 34,
          "Dateentered": "1993-10-07T00:00:00.000Z",
          "Modified": 34,
          "Datemodified": "2003-02-24T00:00:00.000Z",
          "Expert": null,
          "Datechecked": null,
          "TS": null
      "error": null


    GET [/genera{?genus}{?species}{?limit}{?offset}{?fields}]

    List genera

    curl "" |  jq .count

    Genera by id

    GET [/genera/{id}]

    List genera by id

    curl "" |  jq .


    GET [/intrcase{?limit}{?offset}{?fields}]

    Search the intrcase table

    curl "" |  jq .


    GET [/listfields{?fields}{?exact}]

    List fields across all tables. Optionally, search for particular fields. In addition, toggle the exact parameter to search for an exact match.

    curl "" |  jq .


    GET [/maturity{?limit}{?offset}{?fields}]

    Search the maturity table

    curl "" |  jq .


    GET [/morphdat{?limit}{?offset}{?fields}]

    Search the morphdat table


    GET [/morphmet{?limit}{?offset}{?fields}]

    Search the morphmet table


    GET [/occurrence{?limit}{?offset}{?fields}]

    Search the occurrence table


    GET [/oxygen{?limit}{?offset}{?fields}]

    Search the oxygen table


    GET [/popchar{?limit}{?offset}{?fields}]

    Search the popchar table


    GET [/popgrowth{?limit}{?offset}{?fields}]

    Search the popgrowth table


    GET [/poplf{?limit}{?offset}{?fields}]

    Search the poplf table


    GET [/popll{?limit}{?offset}{?fields}]

    Search the popll table


    GET [/popqb{?limit}{?offset}{?fields}]

    Search the popqb table


    GET [/poplw{?limit}{?offset}{?fields}]

    Search the poplw table


    GET [/predats{?limit}{?offset}{?fields}]

    Search the predats table


    GET [/ration{?limit}{?offset}{?fields}]

    Search the ration table


    GET [/refrens{?limit}{?offset}{?fields}]

    Search the refrens table


    GET [/reproduc{?limit}{?offset}{?fields}]

    Search the reproduc table


    GET [/species{?genus}{?species}{?limit}{?offset}{?fields}]

    List species

    curl "" | jq .
    tibble::as_tibble(species("Labroides bicolor"))
    # A tibble: 1 x 100
                sciname     Genus Species SpeciesRefNo              Author
                  <chr>     <chr>   <chr>        <int>               <chr>
    1 Labroides bicolor Labroides bicolor         2334 Fowler & Bean, 1928
    # ... with 95 more variables: FBname <chr>, PicPreferredName <chr>,
    #   PicPreferredNameM <lgl>, PicPreferredNameF <lgl>, PicPreferredNameJ <lgl>,
    #   FamCode <int>, Subfamily <lgl>, GenCode <int>, SubGenCode <lgl>,
    #   BodyShapeI <chr>, Source <chr>, AuthorRef <lgl>, Remark <lgl>,
    #   TaxIssue <int>, Fresh <int>, Brack <int>, Saltwater <int>,
    #   DemersPelag <chr>, AnaCat <lgl>, MigratRef <lgl>, DepthRangeShallow <int>,
    #   DepthRangeDeep <int>, DepthRangeRef <int>, DepthRangeComShallow <int>,
    #   DepthRangeComDeep <int>, DepthComRef <int>, LongevityWild <lgl>,
    #   LongevityWildRef <lgl>, LongevityCaptive <lgl>, LongevityCapRef <lgl>,
    #   Vulnerability <dbl>, Length <dbl>, LTypeMaxM <chr>, LengthFemale <lgl>,
    #   LTypeMaxF <lgl>, MaxLengthRef <int>, CommonLength <lgl>, LTypeComM <lgl>,
    #   CommonLengthF <lgl>, LTypeComF <lgl>, CommonLengthRef <lgl>, Weight <lgl>,
    #   WeightFemale <lgl>, MaxWeightRef <lgl>, Pic <lgl>, PictureFemale <lgl>,
    #   LarvaPic <lgl>, EggPic <lgl>, ImportanceRef <lgl>, Importance <lgl>,
    #   PriceCateg <chr>, PriceReliability <chr>, Remarks7 <lgl>,
    #   LandingStatistics <lgl>, Landings <lgl>, MainCatchingMethod <lgl>,
    #   II <lgl>, MSeines <int>, MGillnets <int>, MCastnets <int>, MTraps <int>,
    #   MSpears <int>, MTrawls <int>, MDredges <int>, MLiftnets <int>,
    #   MHooksLines <int>, MOther <int>, UsedforAquaculture <chr>, LifeCycle <lgl>,
    #   AquacultureRef <lgl>, UsedasBait <chr>, BaitRef <lgl>, Aquarium <chr>,
    #   AquariumFishII <chr>, AquariumRef <int>, GameFish <int>, GameRef <lgl>,
    #   Dangerous <chr>, DangerousRef <lgl>, Electrogenic <chr>, ElectroRef <lgl>,
    #   Complete <lgl>, GoogleImage <int>, Comments <chr>, Profile <lgl>,
    #   PD50 <dbl>, Emblematic <int>, Entered <int>, DateEntered <chr>,
    #   Modified <int>, DateModified <chr>, Expert <int>, DateChecked <chr>,
    #   TS <lgl>, SpecCode <int>

    Species by id

    GET [/species/{id}]

    List species by id


    GET [/spawning{?limit}{?offset}{?fields}]

    Search the spawning table


    GET [/speed{?limit}{?offset}{?fields}]

    Search the speed table


    GET [/stocks{?limit}{?offset}{?fields}]

    Search the stocks table


    GET [/swimming{?limit}{?offset}{?fields}]

    Search the swimming table


    GET [/synonyms{?limit}{?offset}{?fields}]

    Search the synonyms table

    curl "" | jq '[.data[] | {genus: .SynGenus, species: .SynSpecies}]'
        "genus": "Bolbomatopon",
        "species": "muricatum"
        "genus": "Bolbometopon",
        "species": "muricantum"
        "genus": "Bolbometopon",
        "species": "muricatum"
        "genus": "Bolbometopon",
        "species": "muricatus"
        "genus": "Bulbometopon",
        "species": "muricatum"
        "genus": "Callyodon",
        "species": "muricatus"
        "genus": "Scarus",
        "species": "muricatus"
    synonyms("Callyodon murica")
    # A tibble: 1 x 12
      SynCode SpecCode  SynGenus SynSpecies  Status Valid       Synonymy
        <int>    <int>     <chr>      <chr>   <chr> <lgl>          <chr>
    1   59804     5537 Callyodon  muricatus synonym FALSE senior synonym
    # ... with 5 more variables: Combination <chr>, Misspelling <lgl>,
    #   CoL_ID <lgl>, TSN <lgl>, WoRMS_ID <int>


    GET [/taxa{?limit}{?offset}{?fields}]

    Search the taxa table

    curl "" | jq .
      "count": 1,
      "returned": 1,
      "data": [
          "SpecCode": 48051,
          "Genus": "Asprocottus",
          "Species": "parmiferus",
          "SpeciesRefNo": 26334,
          "Author": "Taliev, 1955",
          "FBname": null,
          "FamCode": 584,
          "GenCode": 5868,
          "SubGenCode": null,
          "Remark": null,
          "SubFamily": null,
          "Family": "Abyssocottidae",
          "Order": "Scorpaeniformes",
          "Class": "Actinopterygii"
      "error": null

    API Clients

    R - rfishbase

    rOpenSci maintains this client, and tracks changes in the API closesly


    Not made yet ...