> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.pinnacle.sh/v-2/api-reference/forms/get-form/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pinnacle.sh/_mcp/server. # Get Form GET https://api.pinnacle.sh/forms/{id} Retrieve a form by id. Includes submission count, last submission timestamp, and archive state. Reference: https://docs.pinnacle.sh/api-reference/forms/get-form ## Authentication - `PINNACLE-API-KEY` header (required) — API Key authentication via header ## Request ### Path parameters - `id` (string, required) — The unique identifier of the form you want to retrieve. This identifier is a string that always begins with the prefix `form_`, for example: `form_Oy2n7iUoi9CJwUU6`. It's returned on every form response (`Form.id`) and by [`POST /forms/send`](/api-reference/forms/send-form) (`response.form.id`). ## Response ### 200 The form. - `id` (string, required) — Form id (starts with `form_`). - `url` (string, required) — Public shareable URL of the form (`https://forms.pinnacle.sh/{form_id}`). - `name` (string, required, nullable) — Human-readable name for the form. Rendered as the form's title. - `description` (string, required, nullable) — Longer description rendered below the title. - `fields` (list of FormField, required) — Ordered list of fields the recipient fills out. - `can_update` (boolean, required) — When true, the recipient can reopen the submission URL and edit their answers. When false, the URL becomes read-only after the first submit. - `expires_at` (string, required, nullable) — After this timestamp the form stops accepting submissions. Null means no expiration. - `theme_override` (FormThemeOverride, required, nullable) — Per-form theme tweaks layered on top of your team's default theme. Null means the team defaults are used as-is. - `submission_count` (integer, required) — Count of distinct completed submissions for this form. Does not increment on edits to an existing `can_update=true` submission. - `last_submitted_at` (string, required, nullable) — Timestamp of the most recent submission event. Updated on each new submit and on each edit of a `can_update=true` submission. - `archived_at` (string, required, nullable) — When set, the form is archived (soft-deleted) and cannot accept new submissions or be updated. Restore by PATCHing `archived_at` back to null. - `created_at` (string, required) — ISO 8601 timestamp of when the form was created. - `updated_at` (string, required) — ISO 8601 timestamp of the most recent form mutation. ## Errors ### 400 Bad Request Error Validation failed. The payload has missing required fields and/or invalid types. See [https://zod.dev/error-formatting](https://zod.dev/error-formatting) for more information. - `description` (string, required) — Human-readable summary of validation failures. - `errors` (ZodErrorErrors, required) — Structured dictionary of issues containing two main sections: - `errors`: Array of global validation errors not tied to specific fields - `properties`: Object mapping field names to their specific validation errors, where each field contains an `errors` array ### 401 Unauthorized Error The request lacks valid authentication credentials or the provided credentials are invalid. Ensure you're including a valid API key in the request headers and that your account has the necessary permissions to access this endpoint. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### 404 Not Found Error The requested resource could not be found. This may occur if the identifier is incorrect, the resource has been deleted, or you don't have permission to access it. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ### 500 Internal Server Error An unexpected error occurred on Pinnacle's servers while processing your request. If this error persists, please contact support with the request details. - `error` (string, required) — Human-readable description of the error that occurred, corresponding to the HTTP status code. ## Types ### FormField A single field definition inside a form. Discriminated by `type`. - `type`: `text` (text) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `max_length` (integer, optional) — Maximum number of characters the submitter may enter. - `min_length` (integer, optional) — Minimum number of characters the submitter must enter. - `pattern` (string, optional) — Regex the value must match. Validated server-side with RE2, so patterns that enable catastrophic backtracking (backreferences, lookarounds) are rejected at form creation. - `placeholder` (string, optional) — Ghost text shown inside the input while it's empty. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `textarea` (textarea) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `max_length` (integer, optional) — Maximum number of characters the submitter may enter. - `min_length` (integer, optional) — Minimum number of characters the submitter must enter. - `pattern` (string, optional) — Regex the value must match. Same RE2 safety check as `TextField.pattern`. - `placeholder` (string, optional) — Ghost text shown inside the input while it's empty. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `address` (address) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `max_length` (integer, optional) — Maximum number of characters in the selected address. - `min_length` (integer, optional) — Minimum number of characters in the selected address. - `pattern` (string, optional) — Regex the value must match. Same RE2 safety check as `TextField.pattern`. Rarely needed for addresses — usually left off. - `placeholder` (string, optional) — Ghost text shown inside the input while it's empty. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `email` (email) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `placeholder` (string, optional) — Ghost text shown inside the input while it's empty. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `url` (url) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `placeholder` (string, optional) — Ghost text shown inside the input while it's empty. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `phone` (phone) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `placeholder` (string, optional) — Ghost text shown inside the input while it's empty. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `number` (number) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `max` (double, optional) — Maximum accepted value. - `min` (double, optional) — Minimum accepted value. - `placeholder` (string, optional) — Ghost text shown inside the input while it's empty. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `step` (double, optional) — Increment between valid values. For example, `step: 0.5` lets the user enter 1, 1.5, 2, etc. - `type`: `range` (range) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `max` (double, optional, default: 100) — Upper bound of the slider. - `min` (double, optional, default: 0) — Lower bound of the slider. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `step` (double, optional) — Increment between adjacent slider stops. - `type`: `rating` (rating) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `max` (integer, optional, default: 5) — Number of stars rendered. - `min` (integer, optional, default: 0) — Minimum allowed rating. `0` means the submitter can clear their selection. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `date` (date) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `max` (string, optional) — Latest selectable date as `YYYY-MM-DD`. - `min` (string, optional) — Earliest selectable date as `YYYY-MM-DD`. - `placeholder` (string, optional) — Ghost text shown inside the input while it's empty. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `time` (time) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `max` (string, optional) — Latest selectable time as `HH:MM` (24-hour). - `min` (string, optional) — Earliest selectable time as `HH:MM` (24-hour). - `placeholder` (string, optional) — Ghost text shown inside the input while it's empty. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `datetime` (datetime) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `max` (string, optional) — Latest selectable instant as an ISO 8601 timestamp. - `min` (string, optional) — Earliest selectable instant as an ISO 8601 timestamp. - `placeholder` (string, optional) — Ghost text shown inside the input while it's empty. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `color` (color) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `select` (select) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `options` (list of FormFieldOption, required) — Choices shown in the dropdown. At least one is required. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `placeholder` (string, optional) — Placeholder row shown when no option is selected (e.g. "Select…"). - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `radio` (radio) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `options` (list of FormFieldOption, required) — Choices shown as radio buttons. At least one is required. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. - `type`: `checkbox` (checkbox) - `key` (string, required) — Programmatic key used as the property name in the submission payload. Must start with a letter or underscore; letters, digits, and underscores only. - `label` (string, required) — Text shown above the input. - `help_text` (string, optional) — Small caption rendered under the input to give the submitter extra context. - `max_selected` (integer, optional) — Maximum number of boxes the submitter may check. Extra boxes become uninteractive once the cap is reached. - `min_selected` (integer, optional) — Minimum number of boxes the submitter must check. - `options` (list of FormFieldOption, optional) — Choices shown as checkboxes. Omit to render a single boolean checkbox. - `required` (boolean, optional, default: false) — When true, the submitter must provide a value. Default false. ### FormThemeOverride Sparse override layered on top of your team's theme. Every field is optional; provided fields replace the corresponding team defaults at render time. URL fields must use `https://`. - `logo_url` (string, optional, nullable) — Logo displayed at the top of the form. Square images render as an inline mark; wide landscape images render as a full-width banner. - `favicon_url` (string, optional, nullable) — Favicon shown in the browser tab when the form page loads. - `theme_mode` (enum, optional) — Rendering mode. `light` forces the light palette, `dark` forces dark, and `auto` follows the respondent's OS-level appearance setting. - Allowed values: `light`, `dark`, `auto` - `colors` (FormThemeOverrideColors, optional) — Per-mode palette overrides. Each mode is an object with optional `primary`, `background`, and `text` hex colors. Omit a mode to inherit the team default for it. - `font_family` (enum, optional) — Typeface stack. `system` uses the respondent's OS default sans-serif. - Allowed values: `inter`, `system`, `serif`, `mono`, `rounded` - `corner_radius` (enum, optional) — Border-radius preset for cards, inputs, and buttons. - Allowed values: `sharp`, `rounded`, `pill` - `content_alignment` (enum, optional) — Horizontal alignment for the form header (title, description, logo). - Allowed values: `left`, `center`, `right` - `background` (FormBackground, optional) — Background layer for the page. Choose solid, gradient, image, or a built-in pattern. - `submit_button_label` (string, optional) — Text shown on the submit button. Defaults to `Submit`. - `success_message` (string, optional) — Message shown on the success panel after a successful submit (unless `redirect_url` is set, in which case the respondent is redirected). - `redirect_url` (string, optional, nullable) — When set, the submitter is redirected here after a successful submit instead of seeing the success panel. - `privacy_url` (string, optional, nullable) — Link target for the `Privacy` footer link. Omit or set to null to hide the link. - `terms_url` (string, optional, nullable) — Link target for the `Terms` footer link. Omit or set to null to hide the link. - `og_image_url` (string, optional, nullable) — Image shown when the form URL is shared in social / messaging link previews (Open Graph). - `og_description` (string, optional, nullable) — Open Graph description used in link previews. Falls back to the form's `description` when unset. ### ZodErrorErrors Structured dictionary of issues containing two main sections: - `errors`: Array of global validation errors not tied to specific fields - `properties`: Object mapping field names to their specific validation errors, where each field contains an `errors` array ### FormFieldOption A single choice inside a `select`, `radio`, or `checkbox` field. - `value` (string, required) — Machine value sent back in the submission payload. - `label` (string, required) — Human label rendered in the form. ### FormThemeOverrideColors Per-mode palette overrides. Each mode is an object with optional `primary`, `background`, and `text` hex colors. Omit a mode to inherit the team default for it. - `light` (FormColorPalette, optional) — Palette used when the form renders in light mode. - `dark` (FormColorPalette, optional) — Palette used when the form renders in dark mode. ### FormBackground Background layer for the form page. Discriminated by `type`. - `type`: `solid` (solid) - `type`: `gradient` (gradient) - `dark` (FormGradient, required) — Gradient used when the form renders in dark mode. - `light` (FormGradient, required) — Gradient used when the form renders in light mode. - `type`: `image` (image) - `blur` (boolean, required) — When true, blurs the background image. - `tint_opacity` (integer, required) — Darkening overlay intensity from 0 (no overlay) to 80 (heavy). Helps preserve text contrast over busy images. - `url` (string, required) — HTTPS URL of the background image. Must start with `https://`. - `zoom` (integer, required) — Scale percentage. 100 is native size; higher values crop the image tighter. - `type`: `pattern` (pattern) - `preset` (enum, required) — Which built-in pattern to render. - Allowed values: `noise`, `dots`, `mesh`, `grid`, `waves`, `topo` ### FormColorPalette Per-mode palette. All three colors are optional; any you omit fall back to the team default for that mode. - `primary` (string, optional) — Accent color used for the submit button, focus rings, filled checkboxes, and other interactive surfaces. - `background` (string, optional) — Page background color. Fallback solid color used by Safari chrome tinting and safe-area regions. - `text` (string, optional) — Body text and label color. ### FormGradient A single light- or dark-mode gradient stop pair. - `from` (string, required) — Starting color of the gradient. - `to` (string, required) — Ending color of the gradient. - `angle` (enum, required) — Direction the gradient runs. `top-bottom` is vertical; `diagonal` runs top-left → bottom-right. - Allowed values: `top-bottom`, `diagonal` ## Examples **Response** ```json { "id": "form_Oy2n7iUoi9CJwUU6", "url": "https://forms.pinnacle.sh/form_Oy2n7iUoi9CJwUU6", "name": "Contact request", "description": "We'll follow up over SMS or RCS.", "fields": [ { "type": "text", "key": "full_name", "label": "Full name", "min_length": 2, "required": true }, { "type": "email", "key": "email", "label": "Email", "required": true } ], "can_update": false, "expires_at": null, "theme_override": null, "submission_count": 12, "last_submitted_at": "2026-04-23T22:15:04.406Z", "archived_at": null, "created_at": "2026-04-01T12:00:00Z", "updated_at": "2026-04-23T22:15:04.430Z" } ``` **SDK Code** ```python Form import requests url = "https://api.pinnacle.sh/forms/form_Oy2n7iUoi9CJwUU6" headers = {"PINNACLE-API-KEY": ""} response = requests.get(url, headers=headers) print(response.json()) ``` ```javascript Form const url = 'https://api.pinnacle.sh/forms/form_Oy2n7iUoi9CJwUU6'; const options = {method: 'GET', headers: {'PINNACLE-API-KEY': ''}}; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go Form package main import ( "fmt" "net/http" "io" ) func main() { url := "https://api.pinnacle.sh/forms/form_Oy2n7iUoi9CJwUU6" req, _ := http.NewRequest("GET", url, nil) req.Header.Add("PINNACLE-API-KEY", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(res) fmt.Println(string(body)) } ``` ```ruby Form require 'uri' require 'net/http' url = URI("https://api.pinnacle.sh/forms/form_Oy2n7iUoi9CJwUU6") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Get.new(url) request["PINNACLE-API-KEY"] = '' response = http.request(request) puts response.read_body ``` ```java Form import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.get("https://api.pinnacle.sh/forms/form_Oy2n7iUoi9CJwUU6") .header("PINNACLE-API-KEY", "") .asString(); ``` ```php Form request('GET', 'https://api.pinnacle.sh/forms/form_Oy2n7iUoi9CJwUU6', [ 'headers' => [ 'PINNACLE-API-KEY' => '', ], ]); echo $response->getBody(); ``` ```csharp Form using RestSharp; var client = new RestClient("https://api.pinnacle.sh/forms/form_Oy2n7iUoi9CJwUU6"); var request = new RestRequest(Method.GET); request.AddHeader("PINNACLE-API-KEY", ""); IRestResponse response = client.Execute(request); ``` ```swift Form import Foundation let headers = ["PINNACLE-API-KEY": ""] let request = NSMutableURLRequest(url: NSURL(string: "https://api.pinnacle.sh/forms/form_Oy2n7iUoi9CJwUU6")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "GET" request.allHTTPHeaderFields = headers let session = URLSession.shared let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in if (error != nil) { print(error as Any) } else { let httpResponse = response as? HTTPURLResponse print(httpResponse) } }) dataTask.resume() ``` > One API for RCS, iMessage, MMS, and SMS. Build, test, and scale every channel — send your first message in minutes, not weeks.