Your First monday.com Integration

Build a working monday.com integration from scratch. You’ll create a project board, add tasks, and read data back.

~15 minutes Beginner

What You’ll Build

By the end of this tutorial, you’ll have a Ruby script that:

  • Creates a new project board on monday.com
  • Adds tasks with status and priority columns
  • Retrieves and displays the data
  • Handles errors gracefully

This covers the fundamentals you’ll use in any monday.com integration.

Prerequisites

Before starting, make sure you have:

  • Ruby 2.7 or higher installed
  • A monday.com account (free trial works)
  • Basic Ruby knowledge (variables, methods, hashes)
  • 10-15 minutes of focused time

Step 1: Installation

Install the monday_ruby gem:

gem install monday_ruby

Verify the installation by checking the version:

gem list monday_ruby

You should see monday_ruby in the output with a version number.

Step 2: Get Your API Token

Every request to monday.com requires authentication. Here’s how to get your token:

  1. Log in to your monday.com account
  2. Click your profile picture in the top-right corner
  3. Select Administration
  4. Go to the Connections section
  5. Select Personal API token in the sidebar
  6. Copy your Personal API Token

Set Up Environment Variable

Create a file called .env in your project directory:

# .env
MONDAY_TOKEN=your_actual_token_here

We’ll use this to keep your token secure.

Step 3: Create Your First Board

Let’s write a script that creates a project board.

Create a new file called monday_tutorial.rb:

require "monday_ruby"
require "dotenv/load"

# Configure the client with your token
Monday.configure do |config|
  config.token = ENV["MONDAY_TOKEN"]
end

# Initialize the client
client = Monday::Client.new

# Create a new board
response = client.board.create(
  args: {
    board_name: "My Project Tasks",
    board_kind: :public
  },
  select: ["id", "name"]
)

if response.success?
  board = response.body.dig("data", "create_board")
  puts "✓ Created board: #{board['name']} (ID: #{board['id']})"
  puts "Board ID: #{board['id']} - Save this, we'll need it!"
else
  puts "✗ Error creating board: #{response.code}"
  puts response.body
end

Install the dotenv gem to load environment variables:

gem install dotenv

Run your script:

ruby monday_tutorial.rb

Expected output:

✓ Created board: My Project Tasks (ID: 1234567890)
Board ID: 1234567890 - Save this, we'll need it!
Verify in monday.com

Open monday.com in your browser. You should see your new “My Project Tasks” board!

Step 4: Add Tasks to Your Board

Now let’s add some tasks to the board. We’ll start simple by creating items with just names:

require "monday_ruby"
require "dotenv/load"

Monday.configure do |config|
  config.token = ENV["MONDAY_TOKEN"]
end

client = Monday::Client.new

# Replace with your board ID from Step 3
BOARD_ID = 1234567890

# Create three tasks
tasks = ["Design database schema", "Set up development environment", "Write API documentation"]

puts "Creating tasks..."

tasks.each do |task_name|
  response = client.item.create(
    args: {
      board_id: BOARD_ID,
      item_name: task_name
    },
    select: ["id", "name"]
  )

  if response.success?
    item = response.body.dig("data", "create_item")
    puts "✓ Created: #{item['name']}"
  else
    puts "✗ Failed to create: #{task_name}"
  end
end

puts "\nAll tasks created!"

Run the script:

ruby monday_tutorial.rb

Expected output:

Creating tasks...
✓ Created: Design database schema
✓ Created: Set up development environment
✓ Created: Write API documentation

All tasks created!

Check your board on monday.com - you should see all three tasks!

Step 5: Discover Column IDs

Before we can update column values, we need to discover what columns exist on the board and their IDs:

require "monday_ruby"
require "dotenv/load"

Monday.configure do |config|
  config.token = ENV["MONDAY_TOKEN"]
end

client = Monday::Client.new

BOARD_ID = 1234567890  # Your board ID

# Query the board to get column information
response = client.board.query(
  args: { ids: [BOARD_ID] },
  select: [
    "name",
    {
      columns: ["id", "title", "type"]
    }
  ]
)

if response.success?
  board = response.body.dig("data", "boards", 0)

  puts "\n📋 Board: #{board['name']}"
  puts "=" * 50
  puts "\nAvailable Columns:"

  board["columns"].each do |column|
    puts "  • #{column['title']} (ID: #{column['id']}, Type: #{column['type']})"
  end

  puts "\n" + "=" * 50
else
  puts "✗ Error fetching board"
  puts response.body
end

Run the script:

ruby monday_tutorial.rb

Expected output:

📋 Board: My Project Tasks
==================================================

Available Columns:
  • Name (ID: name, Type: name)
  • Status (ID: status__1, Type: color)
  • Person (ID: person__1, Type: multiple-person)
  • Date (ID: date4__1, Type: date)

==================================================
Column IDs

Notice that column IDs have auto-generated suffixes like __1 or random characters (e.g., status__1, color_a8d9f). The Status column type is color, not status. Always query the board first to discover the actual column IDs before updating values.

Step 6: Update Column Values

Now that we know the column IDs, let’s update the status for our tasks.

Important: Replace status__1 below with the actual Status column ID you saw in Step 5:

require "monday_ruby"
require "dotenv/load"

Monday.configure do |config|
  config.token = ENV["MONDAY_TOKEN"]
end

client = Monday::Client.new

BOARD_ID = 1234567890  # Your board ID
STATUS_COLUMN_ID = "status__1"  # Replace with your actual Status column ID from Step 5

# First, get the items
response = client.board.query(
  args: { ids: [BOARD_ID] },
  select: [
    {
      items: ["id", "name"]
    }
  ]
)

if response.success?
  board = response.body.dig("data", "boards", 0)
  items = board["items"]

  puts "Updating task statuses...\n"

  # Update each item's status
  items.each_with_index do |item, index|
    status_labels = ["Working on it", "Done", "Stuck"]

    update_response = client.column.update_value(
      args: {
        item_id: item["id"],
        board_id: BOARD_ID,
        column_id: STATUS_COLUMN_ID,
        value: { label: status_labels[index] }
      }
    )

    if update_response.success?
      puts "✓ Updated: #{item['name']}#{status_labels[index]}"
    else
      puts "✗ Failed to update: #{item['name']}"
    end
  end

  puts "\nAll statuses updated!"
else
  puts "✗ Error fetching items"
end

Run the script:

ruby monday_tutorial.rb

Expected output:

Updating task statuses...

✓ Updated: Design database schema → Working on it
✓ Updated: Set up development environment → Done
✓ Updated: Write API documentation → Stuck

All statuses updated!

Check your board on monday.com - you should now see the status labels on each task!

Step 7: Read Data Back

Now let’s query the board to see all our items with their column values:

require "monday_ruby"
require "dotenv/load"

Monday.configure do |config|
  config.token = ENV["MONDAY_TOKEN"]
end

client = Monday::Client.new

BOARD_ID = 1234567890  # Your board ID

# Query the board with items and column values
response = client.board.query(
  args: { ids: [BOARD_ID] },
  select: [
    "name",
    {
      items: [
        "id",
        "name",
        {
          column_values: ["id", "text", "title"]
        }
      ]
    }
  ]
)

if response.success?
  board = response.body.dig("data", "boards", 0)

  puts "\n📋 Board: #{board['name']}"
  puts "=" * 50

  board["items"].each do |item|
    puts "\n#{item['name']}"

    # Find and display the status column
    status = item["column_values"].find { |col| col["title"] == "Status" }
    if status
      puts "  Status: #{status['text']}"
    end
  end

  puts "\n" + "=" * 50
  puts "Total tasks: #{board['items'].length}"
else
  puts "✗ Error fetching board"
  puts response.body
end

Run the script:

ruby monday_tutorial.rb

Expected output:

📋 Board: My Project Tasks
==================================================

Design database schema
  Status: Working on it

Set up development environment
  Status: Done

Write API documentation
  Status: Stuck

==================================================
Total tasks: 3

Step 8: Handle Errors

Professional integrations need error handling. Let’s add it:

require "monday_ruby"
require "dotenv/load"

Monday.configure do |config|
  config.token = ENV["MONDAY_TOKEN"]
end

client = Monday::Client.new

BOARD_ID = 1234567890

def create_task(client, board_id, task_name, status)
  response = client.item.create(
    args: {
      board_id: board_id,
      item_name: task_name,
      column_values: {
        status: { label: status }
      }
    }
  )

  if response.success?
    item = response.body.dig("data", "create_item")
    puts "✓ Created: #{item['name']}"
    true
  else
    puts "✗ Failed to create: #{task_name}"
    puts "  Error code: #{response.code}"
    false
  end
rescue Monday::AuthorizationError
  puts "✗ Authentication failed. Check your API token."
  false
rescue Monday::Error => e
  puts "✗ monday.com API error: #{e.message}"
  false
rescue StandardError => e
  puts "✗ Unexpected error: #{e.message}"
  false
end

# Test error handling
puts "Creating task with proper error handling..."
create_task(client, BOARD_ID, "Test task", "Working on it")

# Test with invalid board ID
puts "\nTesting error handling with invalid board..."
create_task(client, 999999999, "This will fail", "Working on it")

Run it:

ruby monday_tutorial.rb

Expected output:

Creating task with proper error handling...
✓ Created: Test task

Testing error handling with invalid board...
✗ Failed to create: This will fail
  Error code: 200
Error Types

monday_ruby provides specific error classes:

  • Monday::AuthorizationError - Invalid token
  • Monday::ResourceNotFoundError - Board/item doesn’t exist
  • Monday::RateLimitError - Too many requests
  • Monday::Error - General API errors

Complete Script

View the complete script
require "monday_ruby"
require "dotenv/load"

# Configure client
Monday.configure do |config|
  config.token = ENV["MONDAY_TOKEN"]
end

client = Monday::Client.new

def create_board(client, name)
  response = client.board.create(
    args: { board_name: name, board_kind: :public },
    select: ["id", "name"]
  )

  if response.success?
    board = response.body.dig("data", "create_board")
    puts "✓ Created board: #{board['name']} (ID: #{board['id']})"
    board['id'].to_i
  else
    puts "✗ Failed to create board"
    nil
  end
rescue Monday::Error => e
  puts "✗ Error: #{e.message}"
  nil
end

def create_task(client, board_id, name)
  response = client.item.create(
    args: {
      board_id: board_id,
      item_name: name
    }
  )

  if response.success?
    item = response.body.dig("data", "create_item")
    puts "✓ Created task: #{item['name']}"
    true
  else
    puts "✗ Failed to create task: #{name}"
    false
  end
rescue Monday::Error => e
  puts "✗ Error creating task: #{e.message}"
  false
end

def update_task_status(client, board_id, item_id, column_id, status)
  response = client.column.update_value(
    args: {
      item_id: item_id,
      board_id: board_id,
      column_id: column_id,
      value: { label: status }
    }
  )

  if response.success?
    puts "✓ Updated status: #{status}"
    true
  else
    puts "✗ Failed to update status"
    false
  end
rescue Monday::Error => e
  puts "✗ Error updating status: #{e.message}"
  false
end

def display_board(client, board_id)
  response = client.board.query(
    args: { ids: [board_id] },
    select: [
      "name",
      { items: ["id", "name", { column_values: ["id", "text", "title"] }] }
    ]
  )

  if response.success?
    board = response.body.dig("data", "boards", 0)

    puts "\n📋 #{board['name']}"
    puts "=" * 50

    board["items"].each do |item|
      status = item["column_values"].find { |c| c["title"] == "Status" }
      puts "• #{item['name']} - #{status&.dig('text') || 'No status'}"
    end

    puts "=" * 50
    board["items"]
  else
    puts "✗ Failed to fetch board"
    []
  end
rescue Monday::Error => e
  puts "✗ Error: #{e.message}"
  []
end

# Main execution
puts "🚀 Building your first monday.com integration\n\n"

# Step 1: Create board
board_id = create_board(client, "My Project Tasks")
exit unless board_id

puts "\n"

# Step 2: Add tasks
tasks = ["Design database schema", "Set up development environment", "Write API documentation"]

item_ids = []
tasks.each do |task_name|
  if create_task(client, board_id, task_name)
    # Get the created item's ID
    items = display_board(client, board_id)
    item_ids = items.map { |item| item["id"] }
  end
end

puts "\n"

# Step 3: Discover the Status column ID
columns_response = client.board.query(
  args: { ids: [board_id] },
  select: [{ columns: ["id", "title", "type"] }]
)

status_column_id = nil
if columns_response.success?
  board = columns_response.body.dig("data", "boards", 0)
  status_column = board["columns"].find { |col| col["title"] == "Status" }
  status_column_id = status_column["id"] if status_column
  puts "Found Status column ID: #{status_column_id}"
end

puts "\n"

# Step 4: Update task statuses
if status_column_id
  statuses = ["Working on it", "Done", "Stuck"]
  item_ids.each_with_index do |item_id, index|
    update_task_status(client, board_id, item_id, status_column_id, statuses[index])
  end
else
  puts "⚠ Could not find Status column. Skipping status updates."
end

# Step 5: Display final results
display_board(client, board_id)

puts "\n✨ Integration complete! Check monday.com to see your board."

What You’ve Learned

Congratulations! You’ve built a complete monday.com integration. Here’s what you now know:

  • Installing and configuring monday_ruby
  • Authenticating with the API
  • Creating boards programmatically
  • Adding items to boards
  • Discovering column IDs dynamically
  • Updating column values on items
  • Querying data and parsing responses
  • Handling errors gracefully

Next Steps

Now that you understand the basics, explore more:

Learn More Operations

Build Real Use Cases

Deep Dive

Get Help

Stuck? Here’s how to get help:

Happy coding!

Edit this page
Last updated