Skip to content
Finowl

Ruby · Gender prediction

Predict gender from first names in Ruby

Finowl's /v1/gender/name endpoint takes a name and an optional country code and returns its prediction under a data key. From Ruby you read data["result_status"] first: identified means gender and confidence are filled in, while unknown comes with gender set to nil and a reason such as not_found or ambiguous. The script runs four lookups, including Andrea with two countries, because names can lean differently by region.

An unknown result is a normal, charged answer rather than an error, so store it instead of asking again. Predictions are statistical estimates of how a name is typically used, not a person's identity, so keep them to aggregate reporting or light personalization. For thousands of rows in a Rake task, switch to /v1/gender/batch so each request carries up to 50 names.

Steps

  1. 1

    Export FINOWL_API_KEY and save the script as gender.rb.

  2. 2

    Pass a two-letter ISO 3166-1 country code alongside each name whenever your records have one.

  3. 3

    Branch on result_status and keep unknown results, with their reason, in your database.

  4. 4

    Move larger jobs to the batch endpoint, sending at most 50 items per request.

  5. 5

    Let people state or correct their own gender wherever the prediction appears in your product.

Predict gender from first names in Ruby
require "json"
require "net/http"

GENDER_ENDPOINT = URI("https://api.finowl.co/v1/gender/name")

def predict_gender(name, country: nil, retries: 2)
  payload = { name: name }
  payload[:country] = country if country

  response = Net::HTTP.start(GENDER_ENDPOINT.host, GENDER_ENDPOINT.port, use_ssl: true,
                             open_timeout: 5, read_timeout: 15) do |http|
    http.post(GENDER_ENDPOINT.path, JSON.generate(payload),
              "Authorization" => "Bearer #{ENV.fetch("FINOWL_API_KEY")}",
              "Content-Type" => "application/json")
  end

  case response.code.to_i
  when 200
    JSON.parse(response.body).fetch("data")
  when 400
    raise ArgumentError, "Invalid name or country: #{name.inspect}, #{country.inspect}"
  when 401
    raise "FINOWL_API_KEY is missing or invalid"
  when 429
    code = JSON.parse(response.body).dig("error", "code")
    raise "Finowl #{code}; giving up" if code == "quota_exceeded" || retries.zero?

    sleep [response["Retry-After"].to_i, 1].max
    predict_gender(name, country: country, retries: retries - 1)
  else
    raise "Finowl returned HTTP #{response.code}"
  end
end

[["Andrea", "IT"], ["Andrea", "US"], ["Jean", "FR"], ["Kim", nil]].each do |name, country|
  data = predict_gender(name, country: country)
  label = "#{name} (#{country || "no country"})"

  if data["result_status"] == "unknown"
    # Unknown is a normal, billed answer. Store it so you do not ask again.
    puts "#{label}: unknown, reason=#{data["reason"]}"
  else
    percent = (data["confidence"] * 100).round
    puts "#{label}: #{data["gender"]} #{percent}% (source=#{data["source"]})"
  end
end

IN PRODUCTION

Production tips

  • Keep name values under 254 characters to avoid a 400 response. Sending the full name is fine; the response's name field shows which first name Finowl actually evaluated.

  • Single lookups default to ai_mode fallback, which consults AI only when the dataset has no answer. Send options: { ai_mode: "off" } in the body when you want dataset-only results.

  • Record source and confidence_kind with each result. AI answers report model_reported confidence and no sample_count, which you may want to weigh differently in reports.

Each lookup costs 1 credit (3 when it requests AI), with 100 free credits every month. See pricing and error codes.

A FEW GOOD QUESTIONS

Common questions

Predict gender from first names in Ruby

Grab an API key, paste the example and run it. 100 free credits every month.