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_…), ili kliknite Kreiraj isečak formulara da izaberete stek i polja i dobijete gotov isečak sa već ubačenim ključem.
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)
Napravite Turnstile vidžet u Cloudflare kontrolnoj tabli, nalepite njegov tajni ključ u podešavanjima forme na Formhook-u, pa ugradite vidžet u svoj HTML koristeći svoj site key. Formhook-u je potreban samo tajni ključ - on nikada ne napušta Formhook i šalje se isključivo na Cloudflare-ovu tačku za proveru.
<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. Ceo postupak pogledajte na stranici o predaji klijentu.
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+).