Rust: POST request to Google CrunchBase API

I need help sending a POST request to Google CrunchBase. I use Rust, its reqwest crate and basic Google CrunchBase API. Please find my source code below:

// import necessary crates
use reqwest::header::{CONTENT_TYPE, ACCEPT};
use serde_json::{Value};
use serde::{Deserialize, Serialize};
use tokio;

// use async in main function
#[tokio::main]
async fn main() {

    // create client
    let client = reqwest::Client::new();

    // generate url
    let url = "https://api.crunchbase.com/api/v4/searches/organizations?user_key=<my_user_key>";

// create raw string for request body
    let raw_str = r#"
        {
          "field_ids": [
            "identifier",
            "categories",
            "location_identifiers",
            "short_description",
            "rank_org"
          ],
          "order": [
            {
              "field_id": "rank_org",
              "sort": "asc"
            }
          ],
          "query": [
            {
              "type": "predicate",
              "field_id": "funding_total",
              "operator_id": "between",
              "values": [
                {
                  "value": 25000000,
                  "currency": "usd"
                },
                {
                  "value": 100000000,
                  "currency": "usd"
                }
              ]
            },
            {
              "type": "predicate",
              "field_id": "location_identifiers",
              "operator_id": "includes",
              "values": [
                "6106f5dc-823e-5da8-40d7-51612c0b2c4e"
              ]
            },
            {
              "type": "predicate",
              "field_id": "facet_ids",
              "operator_id": "includes",
              "values": [
                "company"
              ]
            }
          ],
          "limit": 50
        }
    "#;

    // send request, await response
    let response = client
        .post(url)
        .body(raw_str)
        .header(CONTENT_TYPE, "application/json")
        .header(ACCEPT,       "application/json")
        .send()  // confirm request with send
        .await   // use await to yield query result
        .unwrap();

    // process response
    match response.status() {

        reqwest::StatusCode::OK => {
            println!("Success: {:?}", response);
        },
        
        reqwest::StatusCode::UNAUTHORIZED => {
            println!("Error: Not authorized. New token is required.");
            println!("Response: {:?}", response);
        },

        other => {
            panic!("Error: Unexpected behaviour! {:?}", other);
        },
    };

}

The code compiles and runs. I can send a request, but I obtain an erroneous response:

Response: Response { url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("api.crunchbase.com")), port: None, path: "/api/v4/searches/organizations", query: Some("user_key=<my_user_key>"), fragment: None }, status: 400, headers: {"content-type": "application/json", "date": "Wed, 17 May 2023 17:43:28 GMT", "server": "openresty", "x-cb-request-took": "2", "content-length": "319", "connection": "keep-alive"} }
thread 'main' panicked at 'Error: Unexpected behaviour! 400', src/main.rs:105:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

I think my potential errors are:

  1. generating a request body from a raw string
  2. using send().await.unwrap() methods of the client

Would you please double check those for me?

What is the response body? I'd assume Google would provide you with some information to why your request was bad.

2 Likes

I think the response body is:

Response { url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("api.crunchbase.com")), port: None, path: "/api/v4/searches/organizations", query: Some("user_key=<my_user_key>"), fragment: None }, status: 400, headers: {"content-type": "application/json", "date": "Wed, 17 May 2023 17:43:28 GMT", "server": "openresty", "x-cb-request-took": "2", "content-length": "319", "connection": "keep-alive"} }

According to Google CrunchBase API the status code should be 200, if the request was successful. In my case it is 400, which means a "bad request". But what was "bad" in there I don't understand.

That's an instance of reqwest's Response type, without the response body. You have to load the response body explicitly. Try printing response.text().await.unwrap() to get the response body as UTF-8 string. Hopefully the body contains an error message that contains information to how and why your request was not successful. I personally assume something is wrong with the JSON you send as part of your request, but we can't be sure about that without the actual error.

3 Likes

Thank you for your help! Please find the response body below:

Response: "[{\"message\":\"insufficient permissions to read field categories\",\"code\":\"MD403\",\"entity_def_id\":\"organization\",\"field_id\":\"categories\",\"entitlement_ids\":[]},{\"message\":\"insufficient permissions to search field funding_total\",\"code\":\"MD403\",\"entity_def_id\":\"organization\",\"field_id\":\"funding_total\",\"entitlement_ids\":[]}]"

It seems I'm unable to use the search functionality of the CrunchBase API. Maybe the free basic access doesn't allow that? I will try to sign up for a free trial to the enterprise version and try again. Thank you for your help so far!

1 Like