Formhook dokumentacija
Nalepite API ključ u action forme, dobijajte unose u kontrolnoj tabli i sistemsko push obaveštenje za svaki novi unos.
Brzi početak
1. Registrujte se i verifikujte imejl.
2. Napravite formu u kontrolnoj tabli. Kopirajte API ključ (izgleda kao fh_…).
3. Nalepite ga kao action svoje HTML forme. To je sve.
HTML forma (bez JavaScripta)
Najjednostavnija integracija. Nativno slanje forme, opciono preusmeravanje pri uspehu.
<form action="https://formhook.app/f/YOUR_API_KEY" method="POST">
<input name="email" type="email" required>
<textarea name="message" required></textarea>
<!-- honeypot: bots fill this, humans don't see it -->
<input type="text" name="_gotcha" tabindex="-1" autocomplete="off"
style="position:absolute;left:-9999px">
<!-- where to send the user after success -->
<input type="hidden" name="_redirect" value="https://example.com/thanks">
<button type="submit">Send</button>
</form>JavaScript fetch
await fetch("https://formhook.app/f/YOUR_API_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
email: "user@example.com",
message: "Hello",
}),
});React komponenta
"use client";
import { useState } from "react";
export function ContactForm() {
const [status, setStatus] = useState<"idle" | "sending" | "ok" | "error">("idle");
async function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
setStatus("sending");
const data = Object.fromEntries(new FormData(e.currentTarget));
const res = await fetch("https://formhook.app/f/YOUR_API_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
setStatus(res.ok ? "ok" : "error");
}
if (status === "ok") return <p>Thanks - we'll be in touch.</p>;
return (
<form onSubmit={onSubmit}>
<input name="email" type="email" required />
<textarea name="message" required />
<button disabled={status === "sending"}>Send</button>
{status === "error" && <p>Something went wrong. Try again.</p>}
</form>
);
}WordPress
Formhook je backend za forme, pa svaka WordPress forma može da šalje ka njemu. Izaberite ono što odgovara vašem podešavanju:
Nativna HTML forma
Ubacite običnu formu u stranicu ili blok i usmerite njen action na svoj endpoint. Dodajte origin svog sajta u Dozvoljene origine forme da bi slanja iz pregledača bila prihvaćena.
<form action="https://formhook.app/f/YOUR_API_KEY" method="POST">
<input name="email" type="email" required>
<textarea name="message" required></textarea>
<input type="hidden" name="_redirect" value="https://your-site.com/thanks">
<button type="submit">Send</button>
</form>Contact Form 7
Prosledite svaki Contact Form 7 unos iz functions.php svoje teme. Pošto zahtev dolazi sa vašeg servera (bez Origin zaglavlja iz pregledača), autentifikujte ga X-Auth-Tokenom:
// functions.php - forward Contact Form 7 submissions to Formhook
add_action('wpcf7_before_send_mail', function ($contact_form) {
$submission = WPCF7_Submission::get_instance();
if (!$submission) return;
$data = $submission->get_posted_data();
wp_remote_post('https://formhook.app/f/YOUR_API_KEY', [
'headers' => [
'Content-Type' => 'application/json',
'X-Auth-Token' => 'YOUR_AUTH_TOKEN',
],
'body' => wp_json_encode($data),
'timeout' => 10,
]);
});Gravity Forms
Koristite zvanični Webhooks dodatak za POST ka svom endpointu, ili prosledite iz functions.php sa istim serverskim tokenom:
// functions.php - forward Gravity Forms submissions to Formhook
add_action('gform_after_submission', function ($entry, $form) {
$payload = [];
foreach ($form['fields'] as $field) {
$payload[$field->label] = rgar($entry, (string) $field->id);
}
wp_remote_post('https://formhook.app/f/YOUR_API_KEY', [
'headers' => [
'Content-Type' => 'application/json',
'X-Auth-Token' => 'YOUR_AUTH_TOKEN',
],
'body' => wp_json_encode($payload),
'timeout' => 10,
]);
}, 10, 2);Generišite token u podešavanjima forme pod Settings → Server request authentication. Pogledajte Origini & autentifikacija za razliku između zahteva iz pregledača i sa servera.
cURL (testiranje)
Zahtevi server-na-server (curl, backend kod) ne šalju Origin zaglavlje, pa moraju da se autentifikuju X-Auth-Token zaglavljem. Generišite token u podešavanjima forme pod Settings → Server request authentication i šaljite ga uz svaki zahtev - bez njega se serverski zahtevi odbijaju.
curl -X POST https://formhook.app/f/YOUR_API_KEY \
-H "Content-Type: application/json" \
-H "X-Auth-Token: YOUR_AUTH_TOKEN" \
-d '{"email":"test@example.com","message":"hi"}'Rezervisana polja
Ova tri imena polja se uklanjaju iz sačuvanog sadržaja:
_gotcha- honeypot. Bilo šta upisano ovde vraća 200 uspeh, ali tiho odbacuje unos i ne troši vašu kvotu._redirect- URL za preusmeravanje pri uspehu (samo form-encoded postovi). Mora biti na originu sa vaše liste dozvoljenih; u suprotnom se ignoriše.cf-turnstile-response- Turnstile token, proverava se na serveru.
CORS
Za slanja iz pregledača dodajte origin (šema + host, bez putanje) u Dozvoljene origine u podešavanjima forme. Prazna lista u potpunosti odbija zahteve iz pregledača. Zahtevi server-na-server (bez Origin zaglavlja, npr. curl ili backend) moraju da pošalju važeće X-Auth-Token zaglavlje generisano u podešavanjima forme; bez tokena se odbijaju.
Cloudflare Turnstile (opciono)
Uključite Turnstile u podešavanjima forme, pa ugradite vidžet u svoj HTML:
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js"
async defer></script>
<form action="https://formhook.app/f/YOUR_API_KEY" method="POST">
<input name="email" type="email" required>
<div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITEKEY"></div>
<button type="submit">Send</button>
</form>Otpremanje fajlova (Pro i Studio)
Forme mogu da primaju priloge. Šaljite sa enctype="multipart/form-data"; svako <input type="file"> polje otprema se u objektno skladište i povezuje sa unosom u kontrolnoj tabli. Fajlovi se preuzimaju preko potpisanih URL-ova kratkog roka iz kontrolne table; ništa nije javno dostupno.
<!-- enctype is the important bit -->
<form action="https://formhook.app/f/YOUR_API_KEY" method="POST" enctype="multipart/form-data">
<input name="email" type="email" required>
<textarea name="message" required></textarea>
<!-- one or more file inputs; same field name = multiple files -->
<input name="attachment" type="file">
<button type="submit">Send</button>
</form>Limit po fajlu: 10 MB. Skladište po nalogu: 1 GB na Pro, 10 GB na Studio paketu. Odgovori mekog odbijanja: {ok: true, warnings: ["file_too_large"]} kada jedan fajl pređe limit po fajlu, ["storage_full"] kada je nalog na granici prostora, ["files_not_configured"] ako operater nije podesio objektno skladište. U svakom slučaju tekstualni unos se ipak čuva.
Studio: pripremite i prenesite klijentske forme
Studio nalozi mogu da naprave formu za klijenta i predaju mu je. Studio podešava i testira dok poseduje formu; nakon prenosa klijent poseduje formu i njene unose, a studio vidi samo metapodatke.
- Na New form popunite opciono polje Client email. Forma se označava kao klijentska (sponzorstvo se beleži), ali je i dalje vi posedujete.
- Podesite i testirajte formu normalno - unosi stižu u vašu kontrolnu tablu dok testirate.
- Kada budete spremni, otvorite Settings → Client transfer sekciju forme i pošaljite pozivnicu. Forma ostaje aktivna i prima unose dok čekate.
- Klijent dobija link imejlom, registruje se (imejl se automatski verifikuje posedovanjem tokena) i klikne Claim. Od tog trenutka unosi stižu u njegovu kontrolnu tablu.
Nakon preuzimanja vidite formu u svojoj konzoli za klijente sa statusom + mesečnim brojem unosa. Više ne vidite sadržaj unosa ni priloge - to je GDPR granica koja vas drži van lanca podataka vaših klijenata. Unosi se i dalje računaju u vaš Studio limit (naplata se objedinjuje); sam klijent može da ostane na Free paketu bez ikakvih problema.
Uvoz unosa
Masovno uvezite unose u formu iz JSON fajla - otvorite formu u svojoj kontrolnoj tabli, kliknite Import i otpremite fajl ovakvog oblika:
{
"schemaVersion": 1,
"submissions": [
{
"payload": { "email": "ada@example.com", "message": "Hello" },
"createdAt": "2025-01-02T15:04:05Z"
}
]
}Najviši nivo može biti niz stavki ili objekat sa nizom submissions. Svakoj stavci treba payload objekat; createdAt (ISO-8601) je opcion i čuva se kada postoji. Uvezeni unosi označavaju se kao pročitani, nikada ne pokreću obaveštenja ni webhookove, a limit je 5.000 po fajlu (najviše 5 MB).
Ograničenja zahteva i kvote
- Po IP adresi preko svih formi: 10 zahteva/minutu → 429 sa
Retry-After. - Po formi: 60 zahteva/minutu → 429.
- Limit veličine tela: 64 KB → 413.
- Mesečna kvota besplatnog paketa: 250 unosa u kliznom prozoru od 30 dana. Preko kvote i dalje vraća 200 sa
warnings: ["over_quota"]u telu - unosi se nikada tiho ne odbacuju.
Odgovori na greške
| HTTP | kod | značenje |
|---|---|---|
| 200 | ok | uspeh |
| 302 | - | preusmeravanje na _redirect URL |
| 400 | invalid_body | neispravan JSON / nepodržan content-type |
| 403 | origin_not_allowed | origin nije na CORS listi |
| 403 | turnstile_failed | Turnstile token nedostaje/neispravan |
| 403 | account_suspended | vlasnik forme je suspendovan |
| 404 | form_not_found | nepoznat api_key |
| 413 | body_too_large | telo > 64 KB |
| 429 | rate_limited | uključuje Retry-After zaglavlje |
| 500 | internal_error | pokušajte ponovo, ili prijavite |
Push obaveštenja (za vas, vlasnika forme)
Otvorite kontrolnu tablu i kliknite Enable notifications - pregledač će zatražiti dozvolu, a zatim svaki novi unos pokreće sistemsko obaveštenje, čak i kada je kartica zatvorena. Na iOS-u prvo instalirajte Formhook na početni ekran (Safari 16.4+).