Zabbix API starts to play significant role especially when it comes to integration of Zabbix with third-party software like configuration and incident management systems as well as for automation of routine tasks. It is incredibly difficult to manage monitoring of thousands of hosts without some automation in place!

The API was introduced in Zabbix 1.8 and is already used widely. All Zabbix mobile clients are based on the API, even the native WEB front-end is partially built on top of it. The API middleware makes the architecture more modular and helps to avoid direct calls to the database.

Zabbix API provides two main functions:

  • remote management of Zabbix configuration
  • remote retrieval of configuration and historical data

Preparing environment

I will use Perl for my “Hello API” example. Zabbix API is based on JSON-RPC 2.0 specification and Perl provides a very nice module for working with JSON-RPC protocol called JSON::RPC.

On my Ubuntu desktop I didn’t have it installed, so I had to run apt-get:

sudo apt-get install libjson-rpc-perl

Great! Now we are ready to do some hacking.

Authentication

Any Zabbix API client has to authenticate itself before doing actual work. User.login method is exactly what we need.

The method accepts a user name and a password and returns back Authentication ID, a secure hash used for consecutive API calls.

Look at auth.pl:

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;
use JSON::RPC::Client;
use Data::Dumper;

# Authenticate yourself
my $client = new JSON::RPC::Client;
my $url = 'http://testserver.zabbix.com/zabbix/api_jsonrpc.php';
my $authID;
my $response;

my $json = {
jsonrpc => "2.0",
method => "user.login",
params => {
user => "Admin",
password => "zabbix"
},
id => 1
};

$response = $client->call($url, $json);

# Check if response was successful
die "Authentication failed\n" unless $response->content->{'result'};

$authID = $response->content->{'result'};
print "Authentication successful. Auth ID: " . $authID . "\n";

Note that you should alter $url and also the user name and the password to match your setup.

Let’s run it:

[email protected]:~$ ./auth.pl
Authentication successful. Auth ID: 15ff2edb84ce8e16585e035da42c1e9d
[email protected]:~$

So far so good. Our auth.pl connected and authenticated successfully. Now we have the Authentication ID, which could be re-used for new API calls.

Getting list of hosts

The script hosts.pl does exactly what auth.pl did before but also executes method host.get for getting list of available hosts.

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;
use JSON::RPC::Client;
use Data::Dumper;

# Authenticate yourself
my $client = new JSON::RPC::Client;
my $url = 'http://testserver.zabbix.com/zabbix/api_jsonrpc.php';
my $authID;
my $response;

my $json = {
jsonrpc => "2.0",
method => "user.login",
params => {
user => "Admin",
password => "zabbix"
},
id => 1
};

$response = $client->call($url, $json);

# Check if response was successful
die "Authentication failed\n" unless $response->content->{'result'};

$authID = $response->content->{'result'};
print "Authentication successful. Auth ID: " . $authID . "\n";

# Get list of all hosts using authID

$json = {
jsonrpc=> '2.0',
method => 'host.get',
params =>
{
output => ['hostid','name'],# get only host id and host name
sortfield => 'name', # sort by host name
},
id => 2,
auth => "$authID",
};
$response = $client->call($url, $json);

# Check if response was successful
die "host.get failed\n" unless $response->content->{result};

print "List of hosts\n-----------------------------\n";
foreach my $host (@{$response->content->{result}}) {
print "Host ID: ".$host->{hostid}." Host: ".$host->{name}."\n";
}

The script generates a list of all our hosts sorted by host name:

[email protected]:~$ ./hosts.pl
Authentication successful. Auth ID: a2977c028faa93bb34d4ed9f2d379d9f
List of hosts
-----------------------------
Host ID: 10085 Host: MySQL DB
Host ID: 10086 Host: Oracle DB
Host ID: 10087 Host: PostgreSQL DB
Host ID: 10088 Host: Test 001
Host ID: 10089 Host: Test 002
Host ID: 10090 Host: Test 003
Host ID: 10084 Host: Zabbix server
[email protected]:~$

Data flow

The diagram represents typical data flow when working with Zabbix API. The authentication (method user.login) is a mandatory step needed for getting Authentication ID. The ID allows us to call any method of the API provided we have enough permissions.

I missed method user.logout in my Perl scripts for simplicity sake. The method invalidates the Authentication ID, therefore it cannot be used anymore.

You may also use function Dumper() from the excellent package Data::Dumper in your code in order to get JSON response in a human readable format:

Dumper($response->content);

The result will look like:

$VAR1 = {
'jsonrpc' => '2.0',
'id' => 2,
'result' => [
{
'name' => 'MySQL DB',
'hostid' => '10085'
},
{
'name' => 'Oracle DB',
'hostid' => '10086'
},
{
'name' => 'PostgreSQL DB',
'hostid' => '10087'
},
{
'name' => 'Test 001',
'hostid' => '10088'
},
{
'name' => 'Test 002',
'hostid' => '10089'
},
{
'name' => 'Test 003',
'hostid' => '10090'
},
{
'name' => 'Zabbix server',
'hostid' => '10084'
}
]
};

I hope we learned how to use Zabbix 2.0 API for basic operations. It wasn’t too difficult, right?

Additional reading

26 CommentsClose Comments

26 Comments

  • Avatar
    Posted August 3, 2012 at 10:10 0Likes

    perl, realy?:) Common guys, there are plenty of more funny languages out there:) And several existing clients already.

  • Avatar
    Posted August 3, 2012 at 10:31 0Likes

    Perl rocks.

  • Volker Fröhlich
    Volker Fröhlich
    Posted August 3, 2012 at 13:55 0Likes

    Thank you for that interesting post!

    The first script fails for me on:

    die “Authentication failed\n” unless $response->content->{‘result’};

    Can’t call method “content” on an undefined value at ./auth2.pl line 28.

    • Alexei Vladishev
      Posted August 3, 2012 at 15:29 0Likes

      Volker, are you running 1.8 or 2.0? I haven’t tested it with 1.8. Remember that it is important to enable API access in user group settings if connecting to 1.8.

  • Avatar
    Tiago Soares
    Posted August 3, 2012 at 20:50 0Likes

    Same error as Volker.

    I’m using Zabbix server v2.0.1 (revision 28455) (27 June 2012).

  • Volker Fröhlich
    Volker Fröhlich
    Posted August 6, 2012 at 00:33 0Likes

    That was 1.8. The user has access to the API. I’m under the impression, I don’t even get as far as that. Otherwise the script should terminate in a better way.

    • Alexei Vladishev
      Posted August 7, 2012 at 14:39 0Likes

      I agree, I will try to improve my script to have better error reporting. Now it’s really hard to understand what’s going on in case of any failure.

  • Avatar
    Ricardo Klein
    Posted August 6, 2012 at 14:47 0Likes

    Same error here with zabbix 2.0.0 and 2.0.2
    Can’t call method “content” on an undefined value at ./auth.pl line 28.

  • Avatar
    Ricardo Klein
    Posted August 6, 2012 at 14:57 0Likes

    Hey.. I found what was the problem here:
    I used:

     my $url = 'https://URL/zabbix/api_jsonrpc.php';

    And, the https has maybe confused the response, so, with:

    my $url = 'http://URL/zabbix/api_jsonrpc.php';

    it has worked fine.

    • Avatar
      CmiRKWdOgV
      Posted January 28, 2013 at 15:56 0Likes

      Try this:

      --- SNIP ---
      $client->ua->ssl_opts(verify_hostname => 0);
      $response = $client->call($url, $json);
      --- SNAP ---
      • Avatar

        Or even better

        my $ca_cert = '/etc/ssl/certs/ourca.pem';
        $client->ua->ssl_opts(verify_hostname => 1);
        $client->ua->ssl_opts(SSL_ca_file => $ca_cert);

        Here is the explanations
        http://search.cpan.org/dist/libwww-perl/lib/LWP/UserAgent.pm

        • Avatar
          Posted July 18, 2016 at 14:32 0Likes

          I did had tough time figuring out how i am getting
          “Can’t call method “content” on an undefined value at” error. Below are the values i had set

          $client->ua->ssl_opts(SSL_cert_file => "/etc/httpd/ssl/abcd.crt");
          $client->ua->ssl_opts(SSL_key_file => "/etc/httpd/ssl/abcd.key");
          $client->ua->ssl_opts(SSL_ca_file => "/etc/httpd/ssl/gd_bundle.crt");

          Then used

          print Dumper $client;

          to see if actually those are being set, still i was getting same error. Then i did this, this snippet from JSON::RPC::Client module to see if actually reposnse is being set,

          if($response) {
              if($response->is_error) {
                  print "Res:".$response->error_message;
              } else {
                  print Dumper $response;
              }
          } else {
              print $client->status_line;
          }

          this gave me proper erro, in my case

          501 Protocol scheme 'https' is not supported (LWP::Protocol::https not installed)

          So i installed above module, this solved the issue.
          Thanks all for the pointers guys , cheers.

    • Avatar
      Charles Dunda
      Posted April 4, 2013 at 16:09 0Likes

      And vice versa.. “http” did not work for me but “https” did. Thanks!

  • Avatar
    Tiago Soares
    Posted August 6, 2012 at 23:07 0Likes

    Ricardo,

    That’s it!

    Tks!

  • Avatar
    Posted August 7, 2012 at 10:01 0Likes

    I really miss the method for retrieving a graph as an PNG image 🙁

    • Alexei Vladishev
      Posted August 7, 2012 at 14:40 0Likes

      I hope it will be part of Zabbix 2.2.

      • Richlv
        Posted August 7, 2012 at 15:40 0Likes

        now that was a risky comment right there – at least it had that small safety net of “i hope” 😉

        • Avatar
          Bart Verwilst
          Posted August 14, 2012 at 10:08 0Likes

          While you’re in a risky mood, let me ask ‘When will 2.2 be released?’ 😉

          • Alexei Vladishev
            Posted August 14, 2012 at 14:46 0Likes

            It should be released by 1st of May, 2013. Perhaps a little bit sooner or later.

  • Avatar
    Lukas Maly
    Posted August 8, 2012 at 09:55 0Likes

    Very interest blog supply, but on the hosts.pl missing “}”

    foreach my $host (@{$response->content->{result}}) {
    print “Host ID: “.$host->{hostid}.” Host: “.$host->{name}.”\n”;
    }

    I sested it on Zabbix 2.0.2 and client on Debian 6.0.5.

    Thanks

  • Avatar
    Henrik Johansen
    Posted August 8, 2012 at 13:16 0Likes

    There are a number of problems with the current API implementation – the main concern for working with the API is the lack over proper versioning and backwards compatibility.

    Any application using the API will break when the API changes … and it changes a lot (http://www.zabbix.com/documentation/2.0/manual/appendix/api/changes_1.8_-_2.0).

    Other issues are related to API response inconsistency. One issue is that most select* options make the API responses difficult to parse (a hash inside a hash with a dynamic numeric index), another is the confusing return codes resulting in spagetti code like this :

    case
    when response.has_data?
    # Response is a success and “has data” — it’s not empty. This
    # means we found our host.
    puts response.result
    #=> [{“hostid”=>”10017”}]
    when response.success?
    # Response was succssful but doesn’t “have data” — it’s empty, no
    # such host!
    puts “No such host”
    else
    # Response was an error. Uh oh!
    puts response.error_message
    end

    All in all – the ZBX API is probably one of the most annoying API’s that I had to work with.

    There is a lot of documentation on writing usable API’s out there from various big players (Google. Flicker,etc) …. perhaps worth a read for you …

  • Avatar
    zabbix_user2012
    Posted August 29, 2012 at 22:13 0Likes

    I am trying to run the auth.pl script. I am getting this error:

    “Not a HASH reference at /usr/share/perl5/JSON/RPC/Client.pm at line 193”

    Any hints?

    Thanks

  • Avatar
    Adam Carr
    Posted September 20, 2012 at 11:31 0Likes

    I generate custom monitoring screens over and above Zabbix’s inbuilt maps by calling on the API.

    With 1.8 I used this PHP interface (http://andrewfarley.com/php/zabbix-1-8-api-php-class-v1-0) to pull through data.
    Since 2.0, I now use this PHP interface instead (http://zabbixapi.confirm.ch/)

    Thanks to these I can generate custom graphs exactly to my requirements!