Roistat

Ruby wrapper for the Roistat REST API.

Документация на русском

The gem sends every request with the Api-key header (never as a key query param). Project-scoped calls also send project in the query string.

Official docs differ by language. Prefer help-ru for the method list. help-en documents additional endpoints (dashboards, widgets, and alternate access/counter paths); this gem wraps those as well.

Contents

Installation

Add the gem to the Gemfile:

gem "roistat"

Then run:

bundle install

Or install it directly:

gem install roistat

Rails

Generate the initializer:

rails generate roistat:install

This creates config/initializers/roistat.rb with all configuration options.

Configuration

Global config (Rails-friendly)

Roistat.configure do |config|
  config.api_key = ENV.fetch("ROISTAT_API_KEY")
  config.project = ENV.fetch("ROISTAT_PROJECT_ID")

  # Optional:
  # config.base_url = "https://cloud.roistat.com/api/v1"
  # config.timeout = 30
  # config.open_timeout = 10
  # config.binary_tempfile_threshold = 1_048_576
end

Then use the shared client:

Roistat.client.projects.list

Configuration options

Option Required Default Description
api_key yes Roistat API key (Api-key header)
project yes for project-scoped calls Project id (query project)
base_url no https://cloud.roistat.com/api/v1 API base URL
timeout no 30 Request timeout in seconds
open_timeout no 10 Connection open timeout in seconds
binary_tempfile_threshold no 1048576 (1 MiB) Binary bodies larger than this become a Tempfile

Environment variables (install generator)

Variable Maps to
ROISTAT_API_KEY config.api_key
ROISTAT_PROJECT_ID config.project
ROISTAT_BASE_URL config.base_url (commented in template)
ROISTAT_TIMEOUT config.timeout (commented)
ROISTAT_OPEN_TIMEOUT config.open_timeout (commented)
ROISTAT_BINARY_TEMPFILE_THRESHOLD config.binary_tempfile_threshold (commented)

Clients

Shared client

Roistat.client builds a client from the global configuration.

Explicit client

Use a dedicated instance when you need another project or key:

client = Roistat::Client.new(
  api_key: "",
  project: "12345",
  timeout: 20
)

client.access.user_list

API-key-only client

Some account endpoints do not need a project id:

client = Roistat::Client.new(api_key: "", project_required: false)
client.get("user/projects")

Resource helpers that are API-key-only (projects.list, projects.create) create that client internally.

Blank or whitespace-only credentials raise Roistat::ConfigurationError before any HTTP call.

Low-level HTTP API

Use these for any documented Roistat path that does not have a resource method yet:

client.get("project/calltracking/phone/list", params: {limit: 10})
client.post("project/events/send", body: {name: "purchase"})
client.request(:get, "project/permissions/user/list")

Method signatures

Method Purpose
get(path, params: {}, parse: :json) GET request
post(path, params: {}, body: nil, parse: :json) POST request
request(method, path, params: {}, body: nil, parse: :json) Arbitrary verb

Notes:

  • path is relative to base_url (leading slash is optional).
  • params become query parameters. The client adds project automatically when the client has a project id.
  • body is JSON-encoded. The gem sets Content-Type: application/json.
  • parse: :json (default) returns a parsed Hash/Array.
  • parse: :binary returns a String or Tempfile (see Responses).

Resource APIs

High-level helpers are available on every client:

client.projects
client.access
client.dashboards
client.widgets
client.billing
client.calltracking
client.orders
client.proxy_leads
client.leads
client.managers
client.clients
client.visits
client.events
client.analytics
client.channels
client.statistics
client.indicators
client.lead_hunter
client.emailtracking
client.sms
client.mediaplan
client.speech
client.vpbx

Official parameter details live in the Roistat API docs.

Projects — client.projects

Ruby method HTTP Path Auth
list GET /user/projects API key only
create(name:, currency:) POST /account/project/create API key only
modules_list(method: :get) GET or POST /project/settings/module/list API key + project
counter_list POST /project/settings/counter/list API key + project (help-en)

Examples:

Roistat.client.projects.list
Roistat.client.projects.create(name: "Demo", currency: "RUB")
Roistat.client.projects.modules_list
Roistat.client.projects.modules_list(method: :post)
Roistat.client.projects.counter_list

Access — client.access

Ruby method HTTP Path Auth
user_list GET /project/permissions/user/list API key + project (help-ru)
authorized_users(method: :get) GET or POST /project/access/get-authorized-users API key + project (help-en)
change(**body) POST /project/access/change API key + project (help-en)

Examples:

Roistat.client.access.user_list
Roistat.client.access.authorized_users
Roistat.client.access.authorized_users(method: :post)
Roistat.client.access.change(email: "user@example.com", permissions: ["access_analytics_base_read"])

Dashboards — client.dashboards

Documented on help-en.

Ruby method HTTP Path
list GET /project/dashboards
widgets(dashboard_id:) GET /project/dashboards/{dashboardId}/widgets

Examples:

Roistat.client.dashboards.list
Roistat.client.dashboards.widgets(dashboard_id: 1)

Widgets — client.widgets

Documented on help-en. Default verb is POST (matches curl examples); pass method: :get when needed.

Ruby method HTTP Path
data(widget_id:, method: :post, **body) GET or POST /project/widget/{widgetId}/data

Examples:

Roistat.client.widgets.data(widget_id: 9, period: "2026-01-01-2026-01-31")
Roistat.client.widgets.data(widget_id: 9, method: :get)

Billing — client.billing

Ruby method HTTP Path Auth Response
transactions_list(period:) POST /user/billing/transactions/list API key + project JSON
transactions_export_excel(period:) POST /user/billing/transactions/list/export/excel API key + project binary

period must include from and to (Roistat date strings).

Examples:

period = {
  from: "2026-01-01T00:00:00+0300",
  to: "2026-07-22T23:59:59+0300"
}

Roistat.client.billing.transactions_list(period: period)

file = Roistat.client.billing.transactions_export_excel(period: period)
# String if ≤ 1 MiB, otherwise Tempfile

Calltracking — client.calltracking

Official docs: calltracking API. The gem uses POST for these endpoints.

Ruby method HTTP Path Notes
script_list(**body) POST /project/calltracking/script/list optional body (e.g. is_deleted:)
script_create(**body) POST /project/calltracking/script/create
script_update(**body) POST /project/calltracking/script/update
script_delete(id:) POST /project/calltracking/script/delete
phone_list(**body) POST /project/calltracking/phone/list
phone_prefix_list(**body) POST /project/calltracking/phone/prefix/list
phone_create(phones:) POST /project/calltracking/phone/create
phone_buy(prefix:, count:) POST /project/calltracking/phone/buy
phone_update(**body) POST /project/calltracking/phone/update
phone_delete(phones:) POST /project/calltracking/phone/delete phone ids
call_list(**body) POST /project/calltracking/call/list filters, extend, sort, limit, offset
call_update(**body) POST /project/calltracking/call/update
call_delete(ids:) POST /project/calltracking/call/delete
call_file(call_id:) POST /project/calltracking/call/{id}/file binary (MP3)
call_xls_export(period:) POST /project/calltracking/call/xls/export binary (XLS)
data(period:) POST /project/calltracking/data dashboard analytics
phone_call(**body) POST /project/phone-call create call history row

Examples:

Roistat.client.calltracking.phone_list
Roistat.client.calltracking.script_list(is_deleted: 0)
Roistat.client.calltracking.call_list(
  filters: {and: [["date", ">", "2026-01-01T00:00:00+0000"]]},
  limit: 50
)
Roistat.client.calltracking.data(period: period)
audio = Roistat.client.calltracking.call_file(call_id: 1234)

Orders — client.orders

Official docs: orders API.

Ruby method HTTP Path
list(**body) POST /project/integration/order/list
add(orders) POST /project/add-orders (JSON array body)
info(order_id:) GET /project/orders/{id}/info
external_url(order_id:) GET /project/orders/{id}/external-url
status_list(**body) POST /project/integration/status/list
set_statuses(statuses) POST /project/set-statuses (JSON array body)
custom_fields(**body) POST /project/analytics/order-custom-fields
status_update(order_id:, status_id:) POST /project/integration/order/{id}/status/update
goal_update(order_id:, **body) POST /project/integration/order/{id}/goal/update
update(orders:) POST /project/integration/order/update
delete(order_id:) POST /project/integration/order/{id}/delete
delete_many(ids:) POST /project/integration/order/delete

Examples:

Roistat.client.orders.list(limit: 50)
Roistat.client.orders.status_list
Roistat.client.orders.info(order_id: "order_12345")
Roistat.client.orders.add([
  {id: "1", name: "New order", date_create: "2022-06-19T00:32:12+0000"}
])

Proxy leads — client.proxy_leads

Official docs: proxy leads API. period is YYYY-MM-DD-YYYY-MM-DD in the query string.

Ruby method HTTP Path
list(period:) GET /project/proxy-leads
duplicates(period:) GET /project/proxy-leads/duplicates
get(id:) GET /project/proxy-leads/{id}

Examples:

Roistat.client.proxy_leads.list(period: "2026-01-01-2026-07-22")
Roistat.client.proxy_leads.get(id: "2")

Leads — client.leads

Official docs: lead management API.

Ruby method HTTP Path
list(**body) POST /project/leads/lead/list
status_list(**body) POST /project/leads/status/list
create(**body) POST /project/leads/lead/create
update(**body) POST /project/leads/lead/update

Examples:

Roistat.client.leads.status_list
Roistat.client.leads.list(
  period: {from: "2023-10-17T21:00:00.000Z", to: "2023-11-30T20:59:59.999Z"},
  sort_field: "creation_date",
  limit: 20
)

Managers — client.managers

Official docs: managers API.

Ruby method HTTP Path
list(**body) POST /project/integration/manager/list
add(**body) POST /project/integration/manager/add
update(**body) POST /project/integration/manager/update
delete(id:) POST /project/integration/manager/delete

Examples:

Roistat.client.managers.list
Roistat.client.managers.add(id: "12345", name: "Petrov", email: "a@b.c")

Clients — client.clients

Official docs: clients API.

Ruby method HTTP Path
list(**body) POST /project/clients
import(clients) POST /project/clients/import (JSON array body)
detail_feed(client:) GET /project/clients/detail/feed (client query)
campaign_list(**body) POST /project/clients/campaign/list
campaign_contact_list(**body) POST /project/clients/campaign/contact/list

Examples:

Roistat.client.clients.list(limit: 100)
Roistat.client.clients.detail_feed(client: "123")
Roistat.client.clients.import([{id: "111", name: "Valera"}])

Visits — client.visits

Official docs: visits API.

Ruby method HTTP Path
list(**body) POST /project/site/visit/list
params_update(**body) POST /project/site/visit/params/update

Examples:

Roistat.client.visits.list(limit: 100)
Roistat.client.visits.params_update(visit: "123", roistat_param1: "onlineshop")

Events — client.events

Official docs: events API. send_event avoids shadowing Ruby Kernel#send.

Ruby method HTTP Path
send_event(**body) POST /project/events/send
bulk_send(events) POST /project/events/bulk/send (JSON array)
add(events) POST /project/events/add (JSON array)
log(**params) GET /project/events/log (filters as query params)
archive(event_id:, events:) POST /project/events/meta/{id}/archive (JSON array)

Examples:

Roistat.client.events.log(name: "Cart")
Roistat.client.events.send_event(name: "Purchase", visit: "100001")

Analytics — client.analytics

Official docs: analytics API.

Ruby method HTTP Path
data(**body) POST /project/analytics/data
data_export_excel(**body) POST /project/analytics/data/export/excel (binary)
metrics_new(**body) POST /project/analytics/metrics-new
dimensions(**body) POST /project/analytics/dimensions
dimension_values(**body) POST /project/analytics/dimension-values
attribution_models(**body) POST /project/analytics/attribution-models
list_orders(**body) POST /project/analytics/list-orders
custom_metrics_list(**params) GET /project/analytics/metrics/custom/list
custom_manual_value_list(**body) POST /project/analytics/metrics/custom/manual/value/list
custom_manual_value_add(**body) POST /project/analytics/metrics/custom/manual/value/add
custom_manual_value_delete(**body) POST /project/analytics/metrics/custom/manual/value/delete
funnel_data(**body) POST /project/reports/funnel/data
event_add(**body) POST /project/analytics/event/add

Examples:

Roistat.client.analytics.dimensions
Roistat.client.analytics.metrics_new
Roistat.client.analytics.custom_metrics_list
Roistat.client.analytics.data(
  period: {from: "2026-01-01T00:00:00+0300", to: "2026-07-31T23:59:59+0300"},
  metrics: ["visits"],
  dimensions: ["marker_level_1"]
)

Channels — client.channels

Official docs: channels / source costs API.

Ruby method HTTP Path
source_list(**body) POST /project/analytics/source/list
cost_list(**body) POST /project/analytics/source/cost/list
cost_add(**body) POST /project/analytics/source/cost/add
cost_update(**body) POST /project/analytics/source/cost/update
cost_delete(id:) POST /project/analytics/source/cost/delete

Examples:

Roistat.client.channels.source_list
Roistat.client.channels.cost_list

Statistics — client.statistics

Official docs: statistics API.

Ruby method HTTP Path
get_daily(**body) POST /project/statistics/get-daily (period: YYYY-MM-DD-YYYY-MM-DD in UTC; optional time_zone, channel)

Examples:

Roistat.client.statistics.get_daily(period: "2026-01-01-2026-07-22")

Indicators — client.indicators

Official docs: health indicators API.

Ruby method HTTP Path
list GET /project/health/indicator/list
run_script(indicator_id:) POST /project/health/indicator/{id}/run-script

Examples:

Roistat.client.indicators.list
Roistat.client.indicators.run_script(indicator_id: 7)

Lead hunter — client.lead_hunter

Official docs: lead hunter API.

Ruby method HTTP Path
list(**params) GET /project/lead-hunter/lead/list (filters as query params)

Examples:

Roistat.client.lead_hunter.list

Email tracking — client.emailtracking

Official docs: email tracking API.

Ruby method HTTP Path
list(**body) POST /project/emailtracking/email/list
attachment(email_id:, attachment_id:) GET /project/emailtracking/email/{email_id}/attachment/{attachment_id} (binary)

Examples:

Roistat.client.emailtracking.list(limit: 10)

SMS — client.sms

Ruby method HTTP Path
set_report_enabled(enabled:) POST /project/set-sms-report-enabled (enabled: "0" or "1")

Examples:

Roistat.client.sms.set_report_enabled(enabled: true)

Mediaplan — client.mediaplan

Official docs: mediaplan API.

Ruby method HTTP Path
target_list(**body) POST /project/mediaplan/target/list
target_create(**body) POST /project/mediaplan/target/create
target_update(**body) POST /project/mediaplan/target/update
target_delete(id:) POST /project/mediaplan/target/delete

Examples:

Roistat.client.mediaplan.target_list(
  period: {from: "2026-07-01T00:00:00+0300", to: "2026-07-31T23:59:59+0300"}
)

Speech analytics — client.speech

RU help only. Official docs: speech analytics API.

Ruby method HTTP Path
call_list(**body) POST /project/speech/call/list
call_list_export_excel(**body) POST /project/speech/call/list/export/excel (binary)
call_add(**body) POST /project/speech/call/add
call_comment_update(**body) POST /project/speech/call/comment/update
call_operator_update(**body) POST /project/speech/call/operator/update
call_transcription_list(**body) POST /project/speech/call/transcription/list
dictionary_list(**body) POST /project/speech/dictionary/list
dictionary_custom_create(**body) POST /project/speech/dictionary/custom/create
dictionary_custom_update(**body) POST /project/speech/dictionary/custom/update
dictionary_custom_delete(**body) POST /project/speech/dictionary/custom/delete
dictionary_custom_phrase_list(**body) POST /project/speech/dictionary/custom/phrase/list
settings_list(**body) POST /project/speech/settings/list
settings_update(**body) POST /project/speech/settings/update

Examples:

Roistat.client.speech.dictionary_list
Roistat.client.speech.call_list

Cloud PBX (VPBX) — client.vpbx

RU help only. Official docs: VPBX API.

Ruby method HTTP Path
call_list(**body) POST /project/vpbx/call/list
operator_list(**body) POST /project/vpbx/operator/list
operator_create(**body) POST /project/vpbx/operator/create
operator_update(**body) POST /project/vpbx/operator/update
operator_deactivate(**body) POST /project/vpbx/operator/deactivate
operator_group_list(**body) POST /project/vpbx/operator/group/list
operator_group_create(**body) POST /project/vpbx/operator/group/create
operator_group_update(**body) POST /project/vpbx/operator/group/update
phone_list(**params) GET /project/vpbx/phone/list
phone_create(**body) POST /project/vpbx/phone/create
phone_update(**body) POST /project/vpbx/phone/update
phone_delete(**body) POST /project/vpbx/phone/delete
script_list(**params) GET /project/vpbx/script/list
script_create(**body) POST /project/vpbx/script/create
script_update(**body) POST /project/vpbx/script/update
script_delete(**body) POST /project/vpbx/script/delete
report_data(**body) POST /project/vpbx/report/data
settings_update(**body) POST /project/vpbx/settings/update
settings_file_audio_upload(file:, **fields) POST /project/vpbx/settings/file/audio/upload (multipart)

settings_file_audio_upload sends multipart/form-data via Client#post_multipart. Pass an IO or open file as file:; other keyword args become form fields.

Examples:

Roistat.client.vpbx.phone_list
Roistat.client.vpbx.script_list

Responses

JSON

Successful JSON responses return the parsed body (usually a Hash with string keys).

Binary

With parse: :binary (billing Excel export, calltracking XLS export, call audio, email attachments, speech call export):

Body size Return type
binary_tempfile_threshold (default 1 MiB) String
> threshold Tempfile (caller should close/unlink)

Errors

Roistat API errors with "status": "error" map to typed exceptions:

Roistat error code Exception
authentication_failed Roistat::AuthenticationError
authorization_failed Roistat::AuthorizationError
access_denied Roistat::AccessDeniedError
request_limit_error Roistat::RateLimitError
other / unknown Roistat::Error

Invalid local config raises Roistat::ConfigurationError.

Error instances may expose:

  • code — Roistat error code
  • http_status — HTTP status
  • response_body — parsed body when available

Development

bin/setup
bundle exec rake          # RSpec + RuboCop
# or
mise test
mise lint

Install Lefthook once for pre-commit hooks:

bundle exec lefthook install

Interactive console:

bin/console

Release:

mise release
# or: bundle exec rake release

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/alec-c4/roistat.

License

The gem is available as open source under the terms of the MIT License.