Set a group counter
curl --request PUT \
--url https://api.scrip.dev/v1/groups/{id}/state/counters/{key} \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"value": "42",
"reset_after": "720h"
}
'import requests
url = "https://api.scrip.dev/v1/groups/{id}/state/counters/{key}"
payload = {
"value": "42",
"reset_after": "720h"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({value: '42', reset_after: '720h'})
};
fetch('https://api.scrip.dev/v1/groups/{id}/state/counters/{key}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.scrip.dev/v1/groups/{id}/state/counters/{key}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'value' => '42',
'reset_after' => '720h'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.scrip.dev/v1/groups/{id}/state/counters/{key}"
payload := strings.NewReader("{\n \"value\": \"42\",\n \"reset_after\": \"720h\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://api.scrip.dev/v1/groups/{id}/state/counters/{key}")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"value\": \"42\",\n \"reset_after\": \"720h\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scrip.dev/v1/groups/{id}/state/counters/{key}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"value\": \"42\",\n \"reset_after\": \"720h\"\n}"
response = http.request(request)
puts response.read_body{
"key": "purchases",
"last_reset_at": "2024-01-15T10:30:00Z",
"reset_after": "720h",
"value": "42"
}{
"code": "bad_request",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Invalid request parameters"
}{
"code": "unauthorized",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Missing or invalid credentials"
}{
"code": "not_found",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Resource not found"
}{
"code": "unsupported_media_type",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Content-Type must be application/json"
}{
"code": "internal_error",
"message": "An internal error occurred"
}State
Set a group counter
Set a counter to an absolute value using replace (last-write-wins) semantics. To add to a counter atomically, use the increment endpoint.
PUT
/
v1
/
groups
/
{id}
/
state
/
counters
/
{key}
Set a group counter
curl --request PUT \
--url https://api.scrip.dev/v1/groups/{id}/state/counters/{key} \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"value": "42",
"reset_after": "720h"
}
'import requests
url = "https://api.scrip.dev/v1/groups/{id}/state/counters/{key}"
payload = {
"value": "42",
"reset_after": "720h"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({value: '42', reset_after: '720h'})
};
fetch('https://api.scrip.dev/v1/groups/{id}/state/counters/{key}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.scrip.dev/v1/groups/{id}/state/counters/{key}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'value' => '42',
'reset_after' => '720h'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.scrip.dev/v1/groups/{id}/state/counters/{key}"
payload := strings.NewReader("{\n \"value\": \"42\",\n \"reset_after\": \"720h\"\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://api.scrip.dev/v1/groups/{id}/state/counters/{key}")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"value\": \"42\",\n \"reset_after\": \"720h\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.scrip.dev/v1/groups/{id}/state/counters/{key}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"value\": \"42\",\n \"reset_after\": \"720h\"\n}"
response = http.request(request)
puts response.read_body{
"key": "purchases",
"last_reset_at": "2024-01-15T10:30:00Z",
"reset_after": "720h",
"value": "42"
}{
"code": "bad_request",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Invalid request parameters"
}{
"code": "unauthorized",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Missing or invalid credentials"
}{
"code": "not_found",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Resource not found"
}{
"code": "unsupported_media_type",
"details": {
"expected": "uuid",
"field": "asset_id",
"fields": [
{
"expected": "<unknown>",
"field": "amount",
"message": "This field is required",
"reason": "required",
"received": "-10.00"
}
],
"reason": "invalid",
"received": "not-a-uuid"
},
"message": "Content-Type must be application/json"
}{
"code": "internal_error",
"message": "An internal error occurred"
}Sets a counter value on a group directly. The counter is identified by its key in the URL path. If the counter does not exist, it is created. If it already exists, its value is overwritten with the provided amount.
This is an absolute set with last-write-wins semantics; to add to a counter atomically, use increment counter. You can optionally include
reset_after (a duration string with h, d, or w units, like "24h" or "30d") to configure auto-reset. Pass an empty string to clear an existing reset interval.
For usage patterns and examples, see the State Management guide.
Authorizations
ApiKeyAuthBearerAuth
API key passed in the X-API-Key header.
Body
application/json
Counter value and optional reset_after
⌘I