How to get value from json string using scripts

Hi, I want to get the sunrise and sunset time using scripts. After fetching the data into a variable, I can only retrieve the topmost data tree. How do I get the sunrise and sunset values?

:global latitude "54.3520";
:global longitude "18.6464";

:local apiUrl "https://api.sunrise-sunset.org/json?lat=$latitude&lng=$longitude&date=today&formatted=0";
:local fetchResult [/tool fetch url="$apiUrl" output=user as-value;
# fetchResult = data={"results":{"sunrise":"2025-08-27T03:42:43+00:00","sunset":"2025-08-27T17:51:02+00:00","solar_noon":"2025-08-27T10:46:53+00:00","day_length":50899,"civil_twilight_begin":"2025-08-27T03:06:16+00:00","civil_twilight_end":"2025-08-27T18:27:29+00:00","nautical_twilight_begin":"2025-08-27T02:17:57+00:00","nautical_twilight_end":"2025-08-27T19:15:49+00:00","astronomical_twilight_begin":"2025-08-27T01:21:25+00:00","astronomical_twilight_end":"2025-08-27T20:12:21+00:00"},"status":"OK","tzid":"UTC"};downloaded=0;duration=00:00:01;status=finished

# this works
:put ($fetchResult->"data")

# this not
:put ($fetchResult->"data"->"results"->"sunrise")

You need to use :deserialize from=json $stringWithJson syntax to convert the string in the ->"data" returned from /tool/fetch into another array with JSON string parsed.

:local latitude "54.3520"
:local longitude "18.6464"
:local apiUrl "https://api.sunrise-sunset.org/json?lat=$latitude&lng=$longitude&date=today&formatted=0"

:local fetchResult [/tool fetch url=$apiUrl output=user as-value]
:local jsonData ($fetchResult->"data")

:local parsed [:deserialize from=json $jsonData]

:local sunrise ($parsed->"results"->"sunrise")
:local sunset ($parsed->"results"->"sunset")
:put ("Sunrise: $sunrise")
:put ("Sunset: $sunset")

Or you can make it function to make same code more generic/re-usable:

:global getSunriseSunset do={
    :local apiUrl "https://api.sunrise-sunset.org/json?lat=$latitude&lng=$longitude&date=today&formatted=0"
    :local fetchResult [/tool fetch url=$apiUrl output=user as-value]
    :local jsonData ($fetchResult->"data")
    :local parsed [:deserialize from=json $jsonData]
    :return $parsed
}

to use it:

{
    :local mySunriseSunset [$getSunriseSunset latitude="54.3520" longitude="18.6464"]
    :put "sunrise: $($mySunriseSunset->"results"->"sunrise")"
    :put "sunset: $($mySunriseSunset->"results"->"sunset")"
}

Now you need the actual sunrise / sunset data as a RouterOS time type, you would have do some parsing of the ISO date time returned inside the JSON returned.

Thank you. Everything works now.

i have this script to i want it to fetch and read json file am new to scripting what am i doing wrong in this coz is not working

sample script

URL containing your JSON

:local url "http://yourserver.com/user.json"

Fetch JSON using output=user and as-value

:local fetchResult [/tool fetch url=$url output=user as-value]

Raw JSON returned in "data"

:local jsonData ($fetchResult->"data")

Parse JSON correctly

:local parsed [:deserialize from=json $jsonData]

Handle both formats: object or array

:local username ""
:local password ""
:local profile ""

If JSON is array ["u","p","pr"]

:if ([:typeof ($parsed->0)] != "nothing") do={
:set username ($parsed->0)
:set password ($parsed->1)
:set profile ($parsed->2)
} else={

JSON is object {"username":"u",...}

:set username ($parsed->"username")
:set password ($parsed->"password")
:set profile ($parsed->"profile")
}

Log parsed values

/log info "Parsed User: $username / $password / $profile"

Create UserManager user if not exists

:local userId [/user-manager user find name=$username]

:if ($userId = "") do={

/user-manager user add \
    name=$username \
    password=$password \
    subscriber-profile=$profile

:log info ("UM User created: $username with profile $profile")

} else={
:log info ("UM User already exists: $username")
} this is my json file content ["testuser1", "1234", "bronze"] or [
{
"username": "testuser1",
"password": "1234",
"profile": "bronze"
}
] what am i doing wrong or how it should it be done

At quick glance those look right. You don't have some sample JSON you're parsing so hard to know for sure.

Now... My guess... If you're using code with :local in the CLI to "test" these operations... local variables disappear (go out of scope) at the end of the command line. If you're running these an a /system/script or scheduler, local is fine. But at CLI all locals used must be done in same command line, this can be done by using { and } block at beginning/end of CLI commands that use the locals. So example,

[admin@MikroTik] > {
:local url "http://yourserver.com/user.json"
:local fetchResult [/tool fetch url=$url output=user as-value]
:local username ""
:local password ""
:local profile ""
# ... more code
:if ([:typeof ($parsed->0)] != "nothing") do={
    :set username ($parsed->0)
    :set password ($parsed->1)
    :set profile ($parsed->2)
    }  
# ... rest of your code
} <enter>
[admin@MikroTik] >

Or you could use :global variables at CLI, since those are available after a CLI command ends.

thank you for replay i realised the problem is with the \ backlash on this code /user-manager user add \ name=$username \ password=$password \ i want some insight on the next issue is when i run the script manual it run fine and create a user on userman and run count increase but when i run it from rest api run count increase but fails to create user on userman even running it with all permistion check both on script and on the user group policy is the script limited previlages if it runs from a rest api

Is the user that owns the script the same account that's logging in to REST API? Those have to match AFAIK (i.e. if you login as "myadmin" but rest api uses an account "myrestlogin", I don't think that's allowed).

You can also try setting dont-require-permissions =yes on system script, to confirm it's permissions related.

Also, the permissions on the script apply to the code within the script (and what that script code is allowed to do) - it does not effect access to the script, that's controlled by user. REST API should have same permission as account used to login in with REST.

But as noted above, account name has to be same to run the script (or you say permission not required).