Check whether the Grona snippet is on a page
package main
import ( "fmt" "strings" "net/http" "io")
func main() {
url := "https://api.grona.ai/v1/websites/verify-script"
payload := strings.NewReader("{ \"url\": \"https://shop.example.com/\" }")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>") req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close() body, _ := io.ReadAll(res.Body)
fmt.Println(res) fmt.Println(string(body))
}OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");RequestBody body = RequestBody.create(mediaType, "{ \"url\": \"https://shop.example.com/\" }");Request request = new Request.Builder() .url("https://api.grona.ai/v1/websites/verify-script") .post(body) .addHeader("Authorization", "Bearer <token>") .addHeader("Content-Type", "application/json") .build();
Response response = client.newCall(request).execute();const url = 'https://api.grona.ai/v1/websites/verify-script';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"url":"https://shop.example.com/"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.grona.ai/v1/websites/verify-script \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "url": "https://shop.example.com/" }'Loads the page at url and looks for your workspace’s Grona snippet on it. The call
waits for the check, so the result is always present or absent, never checking
or unknown. absent also covers a page Grona could not load.
The check covers the one page you send, not the whole site. For how Grona matches a URL
to your website, and for the cases that read absent even though the snippet is
installed, see Verify installations.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
An http or https page URL.
Example
{ "url": "https://shop.example.com/"}Responses
Section titled “Responses”The result of the check.
object
object
The page that was checked.
object
absent also covers a page Grona could not load.
ISO 8601 in UTC, with millisecond precision.
object
The workspace resolved from the secret key.
Examples
Snippet found
{ "data": { "url": "https://shop.example.com/", "script": { "status": "present", "checkedAt": "2026-10-20T09:28:43.162Z" } }, "meta": { "workspaceId": "65e8a1c47d2f9b03e6a15c42" }}Snippet not found, or the page could not be loaded
{ "data": { "url": "https://shop.example.com/recipes/", "script": { "status": "absent", "checkedAt": "2026-10-20T09:29:05.471Z" } }, "meta": { "workspaceId": "65e8a1c47d2f9b03e6a15c42" }}url is missing or is not an http or https URL. error.code is invalid_request.
object
object
Stable and machine-readable. Branch on this, and on the HTTP status for codes you do not know.
Human-readable. The wording can change, so do not parse it.
Example
{ "error": { "code": "invalid_request", "message": "`url` must be an http or https URL." }}The secret key is missing, malformed, unknown or revoked. error.code is unauthorized.
object
object
Stable and machine-readable. Branch on this, and on the HTTP status for codes you do not know.
Human-readable. The wording can change, so do not parse it.
Example
{ "error": { "code": "unauthorized", "message": "Missing or invalid API key." }}Too many requests. Retry with exponential backoff and jitter, and wait at least as long
as Retry-After when it is present. Branch on the status code; the body is not
guaranteed to use the error envelope.
Headers
Section titled “Headers”How long to wait before retrying, in seconds or as an HTTP date.
Unexpected server error. error.code is internal_error. Retry with backoff; if it
persists, contact support@grona.ai with the time of the request and the endpoint.
object
object
Stable and machine-readable. Branch on this, and on the HTTP status for codes you do not know.
Human-readable. The wording can change, so do not parse it.
Example
{ "error": { "code": "internal_error", "message": "Something went wrong on our side." }}Temporarily unavailable. Retry with exponential backoff and jitter, and wait at least as
long as Retry-After when it is present. Branch on the status code; the body is not
guaranteed to use the error envelope.
Headers
Section titled “Headers”How long to wait before retrying, in seconds or as an HTTP date.