Skip to content
Myra EU CAPTCHA Online Help Updated · 25 Aug 2026

Ruby

The eu_captcha gem verifies the token on the server. It has no other dependencies and uses net/http from the standard library of Ruby.

Requirements

The following requirements must be met:

Requirement Value
Ruby From version 2.7
Credentials Public sitekey and secret from the Details view

Install the gem

Install the gem:

gem install eu_captcha

As an alternative, add this line to the Gemfile file:

gem 'eu_captcha'

Embed the widget

Add the script link to each page that has a form to protect:

<script src="https://cdn.eu-captcha.eu/verify.js" async defer></script>

Add the widget to the form:

<div class="eu-captcha" data-sitekey="EUCAPTCHA_SITE_KEY"></div>

Note

In a single-page application with React, Vue, or Angular, embed the widget with the applicable npm package. Then the gem does only the verification on the server.

Verify the token

Verify the transmitted token on the server:

require 'eu_captcha'

captcha = EuCaptcha::Client.new(
  sitekey: ENV['EUCAPTCHA_SITE_KEY'],
  secret:  ENV['EUCAPTCHA_SECRET_KEY']
)

result = captcha.validate(
  token:       params['eu-captcha-response'],
  remote_addr: request.ip
)

render_error unless result.success?

Options

You give these options to the constructor as keyword arguments:

Option Type Default Effect
sitekey String Public sitekey. The value is necessary.
secret String Secret key. The value is necessary and must not occur in the browser.
fail_default Boolean true Return value for the network condition and the token condition when the API is not available. true permits the transmission, false rejects it.
check_cdn_headers Boolean true Gets the IP address of the visitor from the HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, and HTTP_X_REAL_IP headers of the Rack environment before REMOTE_ADDR is used.
verify_url String Address of the production environment Overwrites the address of the /verify endpoint. Use the option for tests.
credentials_url String Address of the production environment Overwrites the address of the /verify-credentials endpoint.

The result object

validate gives an EuCaptcha::Result object with these methods:

Method Return value
success? true when the API was available and the token is valid.
success_network? true when the call of the API completed without a network error or a transmission error.
success_token? true when the API reported the transmitted token as valid.
train true, false, or nil.

The separate query tells a failed challenge from a malfunction of the API:

result = captcha.validate(token: params['eu-captcha-response'], remote_addr: request.ip)

unless result.success_network?
  # Could not reach the API — consider logging or alerting
end

unless result.success_token?
  # Token was rejected — the submission is likely automated
end

Warning

train gives true when the API did not do the applicable verification and forced a positive result. This occurs when the sitekey does not exist, when the secret does not agree with it, or when the protection of the sitekey is off. success? already reads this flag and gives false in this condition. For a network error, train gives the nil value.

Verify the credentials

With verify_credentials, you verify the sitekey and the secret without a token from the browser, for example at the start of the application:

captcha = EuCaptcha::Client.new(
  sitekey: ENV['EUCAPTCHA_SITE_KEY'],
  secret:  ENV['EUCAPTCHA_SECRET_KEY']
)

unless captcha.verify_credentials
  # Credentials are invalid or the API is unreachable — log and alert
end

For a network error or an API error, the method gives false and causes no exception.

See Verify the sitekey and the secret.

Ruby on Rails

Put the credentials in config/credentials.yml.enc and make the client in an initializer file.

The config/initializers/eu_captcha.rb file:

EU_CAPTCHA = EuCaptcha::Client.new(
  sitekey: Rails.application.credentials.dig(:eucaptcha, :sitekey),
  secret:  Rails.application.credentials.dig(:eucaptcha, :secret)
)

Verify the token in the controller:

class ContactController < ApplicationController
  def create
    result = EU_CAPTCHA.validate(
      token:       params['eu-captcha-response'],
      remote_addr: request.ip,
      user_agent:  request.user_agent
    )

    unless result.success?
      render json: { error: 'CAPTCHA verification failed' }, status: :unprocessable_entity
      return
    end

    # process the form...
  end
end

request.ip obeys the setting of the trusted upstream systems of Rails.

Sinatra and Rack

Give the Rack environment to the gem, so that the gem gets the IP address and the identifier of the browser itself:

require 'sinatra'
require 'eu_captcha'

CAPTCHA = EuCaptcha::Client.new(
  sitekey: ENV['EUCAPTCHA_SITE_KEY'],
  secret:  ENV['EUCAPTCHA_SECRET_KEY']
)

post '/contact' do
  result = CAPTCHA.validate(
    token:    params['eu-captcha-response'],
    rack_env: env
  )

  halt 422, 'CAPTCHA verification failed' unless result.success?

  # process the form...
end

When a Rack environment is given, validate obeys the check_cdn_headers setting.

Full example

See Svelte and Ruby.