Skip to content

JSON module

This module introduces a new type of variable that provides both serialization and de-serialization from JSON format.

The variable provides ways to access objects and arrays to add,replace or delete values from the script.

The correct approach is to consider a json object as a hashtable ( you can put (key;value) pairs, and you can delete and get values by key) and a json array as an array ( you can append, delete and replace values).

Since the JSON format can have objects inside other objects you can have multiple nested hashtables or arrays and you can access these using paths.

This module does not depend on other modules.

Enable this parameter if your input JSONs contain signed integers which do not fit into 4 bytes (e.g. larger than 2147483647, etc.). If the parameter is enabled, 4-byte integers will continue to be returned as integers, while larger values will be returned as strings, in order to avoid the integer overflow.

Default value is false.

Set enable_long_quoting parameter
...
modparam("json", "enable_long_quoting", true)
...
# normalize the "gateway_id" int/string value to be always a string
$var(gateway_id) = "" + $json(body/gateway_id);
...

The json variable provides methods to access fields in json objects and indexes in json arrays.

The json variables will be available to the process that created them from the moment they were initialized. They will not reset per message or per transaction. If you want to use the on a per message basis you should initialize them each time.

The grammar that describes the id is:

  • id = name(identifier)*

  • identifier = key | index

  • key = /string | /$var

  • index = [integer] | [$var] | []

The ”[]” index represents appending to the array. It should only be used when trying to set a value and not when trying to get one.

Negative indexes can be used to access an array starting from the end. So ”[-1]” signifies the last element.

Variables can be used as indexes or keys. Variables that will be used as indexes must contain integer values. Variables that will be used as keys should contain string values.

Trying to get a value from a non-existing path (key or value) will return the NULL value and notice messages will be placed in the log describing the value of the json and the path used.

Trying to replace or insert a value in a non-existing path will cause an error in setting the value and notice messages will be printed in the log describing the value of the json and the path used

Accessing the $json variable
...
$json(obj1/key) = "value"; #replace or insert the (key,value)
#pair into the json object;
$json(matrix1[1][2]) = 1; #replace the element at index 2 in the element
#at index 1 in an array
xlog("$json(name/key1[0][-1]/key2)"); # a more complex example
...
Iterating through an array using variables
...
$json(ar1) := "[1,2,3,4]";
$var(i) = 0;
while( $json(ar1[$var(i)]) )
{
#print each value
xlog("Found:[$json(ar1[$var(i)])]\n");
#increment each value
$json(ar1[$var(i)]) = $json(ar1[$var(i)]) + 1 ;
$var(i) = $var(i) + 1;
}
...

Dynamic traversal of a JSON object or array is possible by using a for each statement, similarly to the indexed pseudo variables iteration. However, note that indexing the $json variable is not supported in any other statements (this refers to indexing the entire variable and not to the indexes accepted in the grammar of the id).

In order to explicitly iterate over a JSON object keys or values, you can use the .keys or .values suffix for the path specified in the id.

iteration over $json object keys
...
$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}";
for ($var(k) in $(json(foo.keys)[*]))
xlog("$var(k) ");
...
iteration over $json object values
...
$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}";
for ($var(v) in $(json(foo.values)[*]))
xlog("$var(v) ");
# equivalent to:
$json(foo) := "{\"a\": 1, \"b\": 2, \"c\": 3}";
for ($var(v) in $(json(foo)[*]))
xlog("$var(v) ");
...
iteration over $json array values
...
$json(foo) := "[1, 2, 3]";
for ($var(v) in $(json(foo)[*]))
xlog("$var(v) ");
...

If the value specified by the id is an integer it will be returned as an integer value.

If the value specified by the id is a string it will be returned as a string.

If the value specified by the id is any other type of json ( null, boolean, object, array ) the serialized version of the object will be returned as a string value. Using this and the ”:=” operator you can duplicate json objects and put them in other json objects ( for string or integer you may use the ”=” operator).

If the id does not exist a NULL value will be returned.

There are 2 operators available for this variable.

This will cause the value to be taken as is and be added to the json object ( e.g. string value or integer value ).

Setting a value to NULL will cause it to be deleted.

Appending integers to arrays
...
$json(array1[]) = 1;
...
Deleting the last element in an array
...
$json(array1[-1]) = NULL;
...
Adding a string value to a json object
...
$json(object1/some_key) = "some_value";
...

This will cause the value to be taken and interpreted as a json object ( e.g. this operator should be used to parse json inputs ).

Initializing an array
...
$json(array1) := "[]";
...
Setting a boolean or null value
...
$json(array1[]) := "null";
$json(array1[]) := "true";
$json(array1[]) := "false";
...
Adding a json to another json
...
$json(array) := "[1,2,3]";
$json(object) := "{}";
$json(object/array) := $json(array) ;
...

The json_pretty variable has the same purpose as the json variable, but prints the JSON object in a pretty format, adding spaces and tabs to make the output more readable.

The json_compact variable has the same purpose as the json variable, but prints the JSON object in a more compact form, without formatting spaces.

The json_compact_noescape variable has the same purpose as the json compact variable, printing the JSON object in the compact form, but without escaping the slashes.

Difference between json_compact and json_compact_noescape
...
$json(obj) := "{}";
$json(obj/path) = "/path/to/some/file";
xlog("The json is: $json_compact(obj)\n");
# will print:
# The json is: {"path":"\/path\/to\/some\/file"}
xlog("The json no escape is: $json_compact_noescape(obj)\n");
# will print:
# The json no escape is: {"path":"/path/to/some/file"}
...
Section titled “json_link($json(dest_id), $json(source_id))”

This function can be used to link json objects together. This will work simillar to setting a value to an object, the only difference is that the second object is not copied, only a reference is created.

Changes to any of the objects will be visible in both of them.

You can use this method either to create references so each time you access the field you don’t have to go through the full path (for speed efficiency and shorter code), or if you have an object that must be added to many other objects and you don’t want to copy it each time (space and speed efficiency).

You can think of this object exactly as a reference in an object-oriented language. Modifying fields referenced by the variable will cause modifications in all the objects, BUT modifying the variable itsef will not cause any changes to other objects.

Creating a reference
...
$json(b) := "[{},{},{}]";
json_link($json(stub), $json(b[0]));
$json(stub/ana) = "are"; #add to the stub
$json(stub/ar) := "[]";
$json(stub/ar[]) = 1;
$json(stub/ar[]) = 2;
$json(stub/ar[]) = 3;
$json(b[0]/ar[0]) = NULL; # delete from the original object
xlog("\nTest link :\n$json(stub)\n$json(b)\n\n");
/*Output:
Test link :
{ "ana": "are", "ar": [ 2, 3 ] }
[ { "ana": "are", "ar": [ 2, 3 ] }, { }, { } ]
*/
$json(stub) = NULL; #delete the stub, no change will happen to the source
xlog("\nTest link :\n$json(stub)\n$json(b)\n\n");
/* Output:
Test link :
<null>
[ { "ana": "are", "ar": [ 2, 3 ] }, { }, { } ]
*/
...
[LOGICAL ERROR] Creating a circular reference
...
$json(b) := "[1]";
/* NEVER do this, it is meant only to show where problems might occur */
json_link($json(b[0]), $json(b)); # replace 1 with a reference to b
xlog("\nTest link :\n$json(stub)\n$json(b)\n\n");
/* this will cause OPENSIPS to crash because it will continuously try
to get b, then b[0], then b ... */
...

json_merge(main_json_var,patch_json_var,output_var))

Section titled “json_merge(main_json_var,patch_json_var,output_var))”

The function can be used to patch merge patch_json_var into main_json_var and the output will be populated into the output_var

Using json_merge
...
$json(val1) := "{}";
$json(val1/test1) = "test_val1";
$json(val1/common_val) = "val_from1";
$json(val2) := "{}";
$json(val2/test2) = "test_val2";
$json(val1/common_val) = "val_from2";
json_merge($json(val1),$json(val2),$var(merged_json));
xlog("we merged and got $var(merged_json) \n");
# will print :
# we merged and got {"test1":"test_val1","common_val":"val_from2","test2":"test_val2"}

Top contributors by DevScore(1), authored commits(2) and lines added/removed(3)

#NameDevScoreCommitsLines++Lines—
1.Liviu Chircu (@liviuchircu)201710092
2.Andrei Dragus194155814
3.Razvan Crainea (@razvancrainea)171360158
4.Stefan Darius135639115
5.Vlad Paiu (@vladpaiu)10713220
6.Bogdan-Andrei Iancu (@bogdan-iancu)862630
7.Vlad Patrascu (@rvlad-patrascu)8419979
8.Maksym Sobolyev (@sobomax)5399
9.Björn Esser (@besser82)5212545
10.Ovidiu Sas (@ovidiusas)42174

All remaining contributors: Nick Altmann (@nikbyte), Darius Stefan, Anca Vamanu, Bence Szigeti, Peter Lemenkov (@lemenkov), Julián Moreno Patiño.

(1) DevScore = author_commits + author_lines_added / (project_lines_added / project_commits) + author_lines_deleted / (project_lines_deleted / project_commits)

(2) including any documentation-related commits, excluding merge commits

(3) ignoring whitespace edits, renamed files and auto-generated files

#NameCommit Activity
1.Stefan DariusJun 2026 - Jul 2026
2.Razvan Crainea (@razvancrainea)Feb 2012 - Jun 2026
3.Darius StefanSep 2025 - Sep 2025
4.Vlad Paiu (@vladpaiu)Jul 2014 - Jan 2025
5.Liviu Chircu (@liviuchircu)Oct 2013 - Dec 2024
6.Maksym Sobolyev (@sobomax)Jan 2021 - Nov 2023
7.Bence SzigetiNov 2023 - Nov 2023
8.Bogdan-Andrei Iancu (@bogdan-iancu)Dec 2010 - Apr 2019
9.Vlad Patrascu (@rvlad-patrascu)May 2017 - Apr 2019
10.Peter Lemenkov (@lemenkov)Jun 2018 - Jun 2018

All remaining contributors: Nick Altmann (@nikbyte), Björn Esser (@besser82), Julián Moreno Patiño, Ovidiu Sas (@ovidiusas), Anca Vamanu, Andrei Dragus.

(1) including any documentation-related commits, excluding merge commits

Last edited by: Razvan Crainea (@razvancrainea), Darius Stefan, Vlad Paiu (@vladpaiu), Liviu Chircu (@liviuchircu), Vlad Patrascu (@rvlad-patrascu), Peter Lemenkov (@lemenkov), Nick Altmann (@nikbyte), Bogdan-Andrei Iancu (@bogdan-iancu), Andrei Dragus.

All documentation files (i.e. .md extension) are licensed under the Creative Common License 4.0