Getting Started With the SOLIDserver DDI REST API

Authenticate against the SOLIDserver REST API, call the core DDI endpoints, and run your first automated IPAM task from a script you write yourself. No prior EfficientIP API experience assumed.

What you will build

SOLIDserver exposes its DDI data through a REST API, which means anything you can do through the interface you can also do from a script. This guide takes the shortest useful path to that: get authenticated, read something real back, then change something. By the end you will have a script that authenticates, lists the subnets in a space, reserves the next free address in one of them with a hostname, and reads it back to prove the change.

  • Authenticate One credential, obtained once and reused on every call that follows.
  • Read Pull a real record back from your own SOLIDserver and confirm it is the object you expected.
  • Write Change something, then verify the change from the API rather than from the interface.

Nothing here needs a framework or an SDK. A terminal, a reachable SOLIDserver and an account with the right rights will do.

This is a starting point, not a reference. Endpoint-by-endpoint detail lives in the full API documentation, linked at the end of each step.

Before you start

Every call below assumes these five are in place. If one is missing the request will usually still return something, which is why it is worth checking now rather than debugging a successful-looking response that contains nothing.

What you need

SOLIDserver version

SOLIDserver 7.0 or later; token authentication needs 8.4.0 or later

Licence or module

The REST API ships with SOLIDserver DDI; no separate module is required

Account and permissions

A dedicated API account with read rights on the IPAM module for Steps 1 and 2, and write rights on the target space for Step 3; SOLIDserver applies role-based access control to API calls

Network access

HTTPS to the management appliance on port 443 from wherever the script runs; a trusted certificate, or an explicit decision to skip verification in the lab only

Local tooling

curl and jq, or the SOLIDserverRest Python library from gitlab.com/efficientip/solidserverrest

Step 1 — Authenticate against the API

Authentication is the only step where getting it wrong looks like getting it right. A rejected request and an empty result set can read the same way in a terminal, so confirm the response before moving on.

SOLIDserver’s native method sends the credentials on every request as two headers, X-IPM-Username and X-IPM-Password, each value base64-encoded. There is no session to open first. HTTP basic authentication also works, and from 8.4.0 you can use a signed API token instead of a password. Every call goes over TLS to https://your-solidserver/rest/<service>.

Make the call

Request: authenticate shell
curl -s "https://solidserver.example.net/rest/ip_site_list" \
  -H "X-IPM-Username: $(printf '%s' 'apiuser' | base64)" \
  -H "X-IPM-Password: $(printf '%s' 'S3cret!' | base64)"
Response: authenticated JSON
[
  {
    "site_id": "2",
    "site_name": "Local",
    "site_is_default": "1"
  }
]

Confirm it worked

A successful response returns HTTP 200 with a JSON array, even if it holds only the default space. If you see HTTP 401 with an empty body instead, go to the troubleshooting section before continuing.

Whatever the call returns, hold on to it. Re-authenticating on every request is the first thing that makes a working script slow, and it is the easiest habit to break early.

Full parameter detail for this endpoint is in the API documentation: the SOLIDserver API package, which customers download from the portal at my.efficientip.com under Documentation and Downloads; the same reference is available in OpenAPI format.

Step 2 — Read data from the core DDI endpoints

Reading comes before writing for a practical reason. A read request that returns the object you expected proves your credentials, your host and your object identifiers are all correct, and it costs nothing if you get it wrong.

Every object type follows the same naming. Spaces are ip_site_list, subnets ip_subnet_list, addresses ip_address_list, DNS zones dns_zone_list and DHCP scopes dhcp_scope_list. Swap _list for _info to fetch one record by id, _count to count, and _create, _update or _delete to change it. IPv6 variants add a 6, as in ip_subnet6_list.

List subnets

Start with a collection rather than a single object. A list call tells you whether you are talking to the right SOLIDserver and what the records on it actually look like, which is usually enough to correct an identifier you had guessed at.

Request: list records shell
curl -s "https://solidserver.example.net/rest/ip_subnet_list?WHERE=site_name%3D%27Local%27%20and%20is_terminal%3D%271%27&TAGS=network.gateway&limit=50" \
  -H "X-IPM-Username: $(printf '%s' 'apiuser' | base64)" \
  -H "X-IPM-Password: $(printf '%s' 'S3cret!' | base64)"
Response: record collection JSON
[
  {
    "subnet_id": "20",
    "subnet_name": "home",
    "start_hostaddr": "192.168.16.0",
    "subnet_size": "256",
    "is_terminal": "1",
    "site_id": "2",
    "tag_network_gateway": "192.168.16.254"
  }
]

Read a single record

Listing gives you an identifier. Reading gives you the whole object. This is the call a script leans on most, because it is how the script checks the current state of a SOLIDserver DDI object before deciding whether to change it.

Request: read one record

shell

curl -s “https://solidserver.example.net/rest/ip_subnet_info?subnet_id=20” \ -H “X-IPM-Username: $(printf ‘%s’ ‘apiuser’ | base64)” \ -H “X-IPM-Password: $(printf ‘%s’ ‘S3cret!’ | base64)”

Filter and paginate

Estates of any size will hit the default page limit on the first list call, so it is worth handling pagination before your script goes anywhere near production data. Filtering server-side rather than in your own code keeps the response small enough to read while you are still working out what the fields mean.

Filter with WHERE, which takes an SQL-style expression such as site_name='Local' and is_terminal='1', URL-encoded. Sort with ORDERBY. Page with limit and offset: pass limit explicitly rather than relying on the server default, and loop until a call returns HTTP 204, which is how SOLIDserver signals an empty page. TAGS pulls related values, such as the subnet gateway, into the same response.

Step 3 — Automate an IPAM task

Reading is safe. Writing is the part you test somewhere that does not matter first. Run this against a lab or staging SOLIDserver, such as the evaluation virtual appliance, with a throwaway space of its own until the response is boring.

⚠ Write operations change live DDI data. Point these calls at a lab or staging SOLIDserver, and confirm the verification read in this section returns what you expect before you run any of it against the production estate.

The task

The first task worth automating is one that gets done often, gets done identically every time, and is easy to check afterwards. That combination is what makes the result trustworthy enough to schedule.

Reserve the next free address in a named subnet and register its hostname in one go. It is the request every provisioning pipeline makes, it is identical every time, and the verification read below proves it worked. Two calls do it: ip_address_find_free proposes addresses, then ip_address_create takes one.

The request

Request: write operation shell
# 1. ask for the next free address in subnet 20
curl -s "https://solidserver.example.net/rpc/ip_address_find_free?subnet_id=20&max_find=1" \
  -H "X-IPM-Username: $(printf '%s' 'apiuser' | base64)" \
  -H "X-IPM-Password: $(printf '%s' 'S3cret!' | base64)"
# returns [{"hostaddr":"192.168.16.100", ...}]

# 2. reserve it with a hostname
curl -s -X POST "https://solidserver.example.net/rest/ip_address_create" \
  -H "X-IPM-Username: $(printf '%s' 'apiuser' | base64)" \
  -H "X-IPM-Password: $(printf '%s' 'S3cret!' | base64)" \
  --data-urlencode "site_id=2" \
  --data-urlencode "hostaddr=192.168.16.100" \
  --data-urlencode "name=app01.lab.example.net"
# returns [{"ret_oid":"39"}]
Request: verification read shell
curl -s "https://solidserver.example.net/rest/ip_address_info?ip_id=39" \
  -H "X-IPM-Username: $(printf '%s' 'apiuser' | base64)" \
  -H "X-IPM-Password: $(printf '%s' 'S3cret!' | base64)"
# expect hostaddr 192.168.16.100 and name app01.lab.example.net

Making it repeatable

One call is a demonstration. What makes it automation is the loop around it: read the current state, decide, write, verify. Wrapping these three requests in that shape is the difference between a script that works once and one you can schedule.

When it does not work

Three failures account for most first attempts. Each one looks like a different problem than it is.

HTTP 401 Unauthorized

Symptom

An empty body and a 401 status on every call, including the first list.

Cause

The credential headers are missing, misnamed, or the values were not base64-encoded before sending.

Fix

Encode both values and send them as X-IPM-Username and X-IPM-Password on each request, or switch to HTTP basic authentication and let the client encode them.

HTTP 204 No Content

Symptom

A successful status but no JSON, which looks like the object does not exist.

Cause

The WHERE clause matched nothing, often because of quoting, or the API account cannot see the objects it was asked for.

Fix

Drop the WHERE clause and list the collection unfiltered; if records appear, fix the quoting, and if none appear, grant the account read rights on that space.

HTTP 400 with an errno in the body

Symptom

A JSON body containing errno and errmsg instead of the record you asked for.

Cause

A required parameter is missing or misspelt, or a value such as hostaddr is outside the subnet you named.

Fix

Read errmsg first: it names the parameter. Check the single-record call for the parent object to confirm the identifiers you are passing.

Anything not covered here is worth raising through support rather than guessing at.

What you can automate from here

Key takeaways

  • Authenticate once and reuse the credential for the life of the script.
  • Read before you write. A read that returns the object you expected rules out three problems at once.
  • Handle pagination on the first list call, not after it silently truncates.
  • Wrap read, decide, write and verify around anything you intend to schedule.

The same four steps cover most of what teams automate against DDI data first: provisioning addresses on demand, keeping DNS records in step with an orchestrator, and retiring records when workloads go away. None of that needs a different API, only a different payload.

Where this fits

SOLIDserver API for IT Automation

Everything above is one use of the API. This is what it is designed to do at estate scale: integration with orchestration and infrastructure-as-code tooling, and DDI as a source of truth other systems can query.

Network automation

Everything EfficientIP publishes on this subject in one place: the definition, the solution pages and the other walkthroughs.

If the term itself is new, start with the definition of network automation.

Related reading