Posting an alert using Grafana 8.0 API: any worked example?

  • My Grafana version: 8.0.4 through Docker WSL 2 based engine running under Win 10. Docker version 3.4.0. Docker-Engine 20.10.7

  • I’d like to set up a sample alert using the Unified Alerting API 1.1.0, as documented here: Swagger Editor

  • What I have tried: I have set up an alert manually in the grafana UI, then downloaded every configuration setting I could (using GET in the API). Finally I have deleted my alert in the UI and tried to POST it back using the API. When posting, it did not work.

  • Using GET, I got information from “alertmanager/grafana/config/api/v1/alerts” and “ruler/grafana/api/v1/rules}” only. I have then deleted the alert from the server, and posted exactly what I have received back to “alertmanager/grafana/config/api/v1/alerts”. This first post worked. Then I tried to post back what I had received from “ruler/grafana/api/v1/rules”. This didn’t work and I got the following error: 404 Client Error: Not Found for url: http://127.0.0.1:3000/api/ruler/grafana/api/v1/rules. If I append a “/{Namespace}” to the request url, I get the following in the http response: b’{“message”:“folder not found”,“status”:“not-found”}’, text: ‘{“message”:“folder not found”,“status”:“not-found”}’, status: 404.
    So, I guess I need to specify a new namespace somewhere else, or what? Maybe I need to “create” a namespace within the first POST request?

  • I expected the second post worked. Why did it not?

  • The following is the json payload sent within the second post:

{'existing folder on server': [{'interval': '1m',
                                    'name': 'some name here',
                                    'rules': [{'annotations': {'__dashboardUid__': 'dahsboard UID here',
                                                               '__panelId__': '2'},
                                               'expr': '',
                                               'for': '5m',
                                               'grafana_alert': {'condition': 'B',
                                                                 'data': [{'datasourceUid': 'UID received with GET',
                                                                           'model': {'format': 'time_series',
                                                                                     'group': [],
                                                                                     'intervalMs': 1000,
                                                                                     'maxDataPoints': 43200,
                                                                                     'metricColumn': 'none',
                                                                                     'rawQuery': True,
                                                                                     'rawSql': 'SELECT\n'
                                                                                               '  '
                                                                                               '$__time(time_recorded),\n'
                                                                                               '  '
                                                                                               'co2\n'
                                                                                               'FROM\n'
                                                                                               '  '
                                                                                               'airthings.measurements\n'
                                                                                               'WHERE\n'
                                                                                               '  '
                                                                                               '$__timeFilter(time_recorded)\n'
                                                                                               '  '
                                                                                               'AND '
                                                                                               'sensor_serial_num '
                                                                                               '= '
                                                                                               "'2930039276'\n"
                                                                                               'ORDER '
                                                                                               'BY '
                                                                                               'time_recorded '
                                                                                               'ASC',
                                                                                     'refId': 'A',
                                                                                     'select': [[{'params': ['value'],
                                                                                                  'type': 'column'}]],
                                                                                     'timeColumn': 'time',
                                                                                     'where': [{'name': '$__timeFilter',
                                                                                                'params': [],
                                                                                                'type': 'macro'}]},
                                                                           'queryType': '',
                                                                           'refId': 'A',
                                                                           'relativeTimeRange': {'from': 604800,
                                                                                                 'to': 0}},
                                                                          {'datasourceUid': '-100',
                                                                           'model': {'conditions': [{'evaluator': {'params': [500],
                                                                                                                   'type': 'gt'},
                                                                                                     'operator': {'type': 'and'},
                                                                                                     'query': {'params': ['A']},
                                                                                                     'reducer': {'params': [],
                                                                                                                 'type': 'avg'},
                                                                                                     'type': 'query'}],
                                                                                     'datasource': '__expr__',
                                                                                     'hide': False,
                                                                                     'intervalMs': 1000,
                                                                                     'maxDataPoints': 43200,
                                                                                     'refId': 'B',
                                                                                     'type': 'classic_conditions'},
                                                                           'queryType': '',
                                                                           'refId': 'B',
                                                                           'relativeTimeRange': {'from': 0,
                                                                                                 'to': 0}}],
                                                                 'exec_err_state': 'Alerting',
                                                                 'id': 3,
                                                                 'intervalSeconds': 60,
                                                                 'namespace_id': 1,
                                                                 'namespace_uid': 'level39_docker',
                                                                 'no_data_state': 'NoData',
                                                                 'orgId': 1,
                                                                 'rule_group': 'CO2 '
                                                                               '@ '
                                                                               'level '
                                                                               '39 '
                                                                               ': '
                                                                               'sensor '
                                                                               '$sensor',
                                                                 'title': 'test_alert_1',
                                                                 'uid': 'uid received here from GET',
                                                                 'updated': '2021-06-24T21:46:10Z',
                                                                 'version': 2}}]}]}

This is instead the payload sent within the first POST:

{'alertmanager_config': {'receivers': [{'grafana_managed_receiver_configs': [{'disableResolveMessage': False,
                                                                              'name': 'email '
                                                                                      'receiver',
                                                                              'secureFields': {},
                                                                              'settings': {'addresses': '<example@email.com>'},
                                                                              'type': 'email',
                                                                              'uid': 'uid received here from GET'}],
                                        'name': 'grafana-default-email'}],
                         'route': {'receiver': 'grafana-default-email'},
                         'templates': None},
 'template_files': None}
  • Is it possible to have a completed worked example about how to create an alert from scratch using the API? Thank you.

You’re on the right track with having to create a folder/namespace first. Once you have that you should be able to continue with your example

Were you able to get this working? I’m fighting the next step in this issue (as are many others, it seems). My “existing folder on server” exists, but I get “rule group name is not valid” in response from the POST. I created the folder via “Create → Folder” dialog in our Grafana page - is that not sufficient? Thanks!

The command I’m trying to use is

curl -X POST \
       -u admin:<password> \
       -H "Content-type: application/json" \
       -d $(cat AlertingRules.json) \
http://<grafanaIP>:3000/api/ruler/grafana/api/v1/rules/AlertingRules

I’ve never really found explicit documentation as to whether this is correct.

Hi I Got same message

“rule group name is not valid”

can anyone help ?

Facing the same issue.

Why are there no replies on creating Alert rules using the API?

The solution for "“rule group name is not valid” is given here: NGalert / Grafana 8 alert feature: How to export / import alerts as yml/json? - #11 by callayn, by ahmed1smael