MetriBeacon
Menu

POST Submit an anonymous contact request

/api/v1/public/contact

Same-origin browser form; JSON or URL-encoded body, at most 64 KiB. The email address is Reply-To only; delivery recipient is fixed. Five attempts per network address in 15 minutes, 100 globally per hour. Success confirms SMTP acceptance; failures preserve input. No attachments or automatic reply.

On this page

Access and permissions

Same-origin browser form; JSON or URL-encoded body, at most 64 KiB. The email address is Reply-To only; delivery recipient is fixed. Five attempts per network address in 15 minutes, 100 globally per hour. Success confirms SMTP acceptance; failures preserve input. No attachments or automatic reply.

No account sign-in is required. Any listed browser-origin checks and rate limits still apply.

Parameters and headers

FieldLocationType and limitsRequiredMeaning
langURL querystring; {"enum":["en","de"]}NoSame-origin browser form; JSON or URL-encoded body, at most 64 KiB. The email address is Reply-To only; delivery recipient is fixed. Five attempts per network address in 15 minutes, 100 globally per hour. Success confirms SMTP acceptance; failures preserve input. No attachments or automatic reply.

Request body

FieldType and limitsRequiredMeaning
$object; {"additionalProperties":false}Yes—
$.emailstring; {"format":"email","maxLength":254}Yes—
$.messagestring; {"maxLength":5000,"minLength":10}Yes—
$.namestring; {"maxLength":100}No—
$.subjectstring; {"maxLength":150,"minLength":1}Yes—
$.websitestring; {"maxLength":0}No—

Responses

application/problem+json

FieldType and limitsRequiredMeaning
$ProblemYes—
$.codestringYesStable machine-readable error code
$.detailstringYesShort localized explanation without internal error details
$.instancestringYesUnique relative identifier /api/v1/requests/{request_id}; not a retrievable resource
$.messagestringYesTemporarily identical to detail for existing clients
$.message_keystringYesStable translation key for changing the displayed language without another request
$.message_paramsobject; {"additionalProperties":true}YesNamed, safely rendered message parameters; never arbitrary HTML
$.request_idstring; {"pattern":"^[0-9a-f]{32}$"}YesServer-generated diagnostic identifier. It contains no login token or credential.
$.statusinteger; {"maximum":599,"minimum":400}Yes—
$.titlestringYesLocalized HTTP status title
$.typestring; {"const":"about:blank"}Yes—

application/problem+json

FieldType and limitsRequiredMeaning
$ProblemYes—
$.codestringYesStable machine-readable error code
$.detailstringYesShort localized explanation without internal error details
$.instancestringYesUnique relative identifier /api/v1/requests/{request_id}; not a retrievable resource
$.messagestringYesTemporarily identical to detail for existing clients
$.message_keystringYesStable translation key for changing the displayed language without another request
$.message_paramsobject; {"additionalProperties":true}YesNamed, safely rendered message parameters; never arbitrary HTML
$.request_idstring; {"pattern":"^[0-9a-f]{32}$"}YesServer-generated diagnostic identifier. It contains no login token or credential.
$.statusinteger; {"maximum":599,"minimum":400}Yes—
$.titlestringYesLocalized HTTP status title
$.typestring; {"const":"about:blank"}Yes—

Retries and asynchronous work

This change does not have a general retry guarantee. If the response is unclear, read the affected resource before trying again. Follow Retry-After waiting times and request new sign-in or action codes when they expire.

Request examples

Replace demo IDs, timestamps and placeholders with your own values. For a retry, keep the same IDs, time and content. These examples do not run requests on this page.

Keep login links, codes, cookies and keys private. Do not print them in logs or share them in support requests.

shell
curl --silent --show-error --output /dev/null --write-out "%{http_code}\n" \
  --request POST \
  --header @"$HOME/.config/metribeacon/headers.txt" \
  --header "Origin: https://metribeacon.com" \
  --header "Content-Type: application/json" \
  --data-binary '{"email":"reader@example.test","subject":"Monitoring question","message":"Please explain the monitoring limits."}' \
  "https://metribeacon.com/api/v1/public/contact"
python
import json
from pathlib import Path
from urllib.request import Request, HTTPRedirectHandler, build_opener
from urllib.error import HTTPError

headers = json.loads((Path.home() / ".config/metribeacon/headers.json").read_text())
headers["Origin"] = "https://metribeacon.com"
headers["Content-Type"] = "application/json"
request = Request("https://metribeacon.com/api/v1/public/contact", data="{\"email\":\"reader@example.test\",\"subject\":\"Monitoring question\",\"message\":\"Please explain the monitoring limits.\"}".encode("utf-8"), headers=headers, method="POST")
class NoRedirect(HTTPRedirectHandler):
    def redirect_request(self, request, fp, code, message, headers, target):
        return None

opener = build_opener(NoRedirect())
try:
    with opener.open(request, timeout=10) as response:
        print(response.status)
except HTTPError as error:
    print(error.code)
    error.close()
javascript
import { readFile } from "node:fs/promises";
import { homedir } from "node:os";
import { join } from "node:path";

const headers = JSON.parse(await readFile(join(homedir(), ".config/metribeacon/headers.json"), "utf8"));
headers["Origin"] = "https://metribeacon.com"
headers["Content-Type"] = "application/json";
const response = await fetch("https://metribeacon.com/api/v1/public/contact", {
  method: "POST", headers, redirect: "manual",
  signal: AbortSignal.timeout(10000), body: "{\"email\":\"reader@example.test\",\"subject\":\"Monitoring question\",\"message\":\"Please explain the monitoring limits.\"}",
});
console.log(response.status);
await response.body?.cancel();
go
package main

import (
  "fmt"
  "net/http"
  "time"
  "encoding/json"
  "os"
  "path/filepath"
  "strings"
)

func main() {
  home, err := os.UserHomeDir(); if err != nil { panic("request failed; credentials and response omitted") }
  raw, err := os.ReadFile(filepath.Join(home, ".config/metribeacon/headers.json")); if err != nil { panic("request failed; credentials and response omitted") }
  var headers map[string]string
  if json.Unmarshal(raw, &headers) != nil { panic("invalid local headers") }
  request, err := http.NewRequest("POST", "https://metribeacon.com/api/v1/public/contact", strings.NewReader("{\"email\":\"reader@example.test\",\"subject\":\"Monitoring question\",\"message\":\"Please explain the monitoring limits.\"}"))
  if err != nil { panic("request failed; credentials and response omitted") }
  for name, value := range headers { request.Header.Set(name, value) }
  request.Header.Set("Origin", "https://metribeacon.com")
  request.Header.Set("Content-Type", "application/json")
  client := &http.Client{Timeout: 10*time.Second, CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
  response, err := client.Do(request)
  if err != nil { panic("request failed; credentials and response omitted") }
  defer response.Body.Close()
  fmt.Println(response.StatusCode)
}