Skip to content

`POST /v1/orgs/{org}/policies/validate`.

POST
/v1/orgs/{org}/policies/validate
curl --request POST \
--url https://api.updawg.net/v1/orgs/example/policies/validate \
--header 'Content-Type: application/json' \
--data '{ "yaml": "example" }'

⚠️ A policy that does not parse is a 200. The endpoint’s job is to report whether a document is valid, and “it is not” is that job done — a 400 would mean the request was wrong, and an editor calling this on every keystroke would spend most of its life looking at errors that are not errors. The 400s here are a missing or oversized yaml, which are wrong requests.

Validating means compiling, not reading fields off the parsed document. It is the same call create and update make, so a document this accepts is a document those will store rather than one that merely looks similar.

org
required
string

Organization slug.

Media typeapplication/json
object
yaml

Option so that a missing field produces this API’s own 400 rather than axum’s plain-text 422 — see DAWG-246 and the note in routes::proposals::reject.

string | null
Examplegenerated
{
"yaml": "example"
}

⚠️ 200 even for a document that does not parse. It was asked whether the document is valid and it answers; a 400 would mean the request was wrong, and an editor calling this per keystroke would spend its life looking at errors that are not errors. Saving the same document is a 400.

Media typeapplication/json
object
enabled
boolean | null
errors
required

⚠️ At most one today. serde stops at the first thing it cannot read, so there is no second error to report — collecting them all needs a parser that keeps going, which this one does not. An array rather than a single object so that the shape does not have to change when it can.

Array<object>

One thing wrong with a policy, where an editor can put a marker.

object
column
integer | null
detail
required

The path serde walked, then what went wrong: rules[0]: unknown field .... The location is not repeated here — it is line and column.

string
line

One-based, as an editor counts. Absent for the two checks that need the whole document and so have no line of their own: a rule naming a rollout the policy does not define, and apply: asap_in_window with no window. Both name the rule by index in detail instead.

integer | null
name

What the document says it is, when it is anything. Absent rather than null-and-empty on a failure, because a half-populated body invites a client to read fields that mean nothing.

string | null
priority
integer | null format: int32
rules
integer | null
valid
required
boolean
Examplegenerated
{
"enabled": true,
"errors": [
{
"column": 1,
"detail": "example",
"line": 1
}
],
"name": "example",
"priority": 1,
"rules": 1,
"valid": true
}

⚠️ Not “the document is invalid” — that is the 200 above. A missing or oversized yaml, which is a wrong request rather than a wrong policy.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string
Examplegenerated
{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

No session.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string
Examplegenerated
{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

Refused: no CSRF token or not this session’s, or not permitted for this role.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string
Examplegenerated
{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

No such organization, or not yours.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string
Examplegenerated
{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

Over the organization’s request limit. Retry-After says when to try again; RateLimit-Limit is the burst.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string
Examplegenerated
{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}