Forms
`forms.list`, `get`, `create`, `update`, `delete`, `publish`, `pause`, `resume`, `duplicate`, `analytics`, `list_starters`, `get_starter`, `list_submissions`, `get_submission`, `delete_submission`, `delete_submissions`, `approve_submission`, `resend_confirmation` and `subscribe`.
Every method
form = client.forms.create( name: "Newsletter sign-up", starter: "newsletter", settings: {audienceIds: ["aud_4c1b8e2a7d9f05c36b4e8a71"]}, publish: true) puts form[:url], form[:subscribeUrl] saved = client.forms.update( form[:id], settings: {doubleOptIn: true, senderAddress: "[email protected]"}, expectedUpdatedAt: form[:updatedAt]) signup = client.forms.subscribe(form[:id], email: "[email protected]", first_name: "Ann", consent: true) client.forms.iterate_submissions(form[:id], status: "pending") do |submission| client.forms.resend_confirmation(form[:id], submission[:id]) if submission[:expired]end stats = client.forms.analytics(form[:id], days: 30)starters = client.forms.list_starters client.forms.pause(form[:id])client.forms.resume(form[:id])copy = client.forms.duplicate(form[:id])client.forms.delete(copy[:id]) puts saved[:senderIssue], signup[:outcome], stats.dig(:totals, :conversion), starters.sizeA form keeps a draft document and the publishedDocument visitors see. update changes the draft and the settings, and publish puts the draft live. Settings take effect at once, published or not, and expectedUpdatedAt refuses a save that would overwrite someone else’s with a 409 version_conflict, raised as OpenEmail::ConflictError.
The fields of a form keep the API’s camelCase names (expectedUpdatedAt:, doubleOptIn), passed as keyword arguments or one Hash, while filters and options are snake_case keywords (status: on list_submissions, offset_minutes: on analytics). A form comes back as a Hash with Symbol keys, so form[:subscribeUrl] reads the address that takes sign-ups.
Reading needs forms:read and changing needs forms:write. approve_submission also needs contacts:write, because it adds a contact. resend_confirmation also needs emails:send, and so does a call that makes the form send mail: turning on doubleOptIn, setting senderAddress or the confirmation email, or publishing or resuming a double opt-in form. delete asks an OAuth access token for a verification code, and an API key never. Until the token has one, delete raises OpenEmail::PermissionError with step_up_required? true.
subscribe signs someone up as the form’s page does and sends no credential, even from a client that holds one, so api_key: is ignored. The answers go in as keyword arguments or one Hash, keyed by the form’s field keys. Every sign-up from one network shares a limit of 40 every ten minutes, so a server relaying sign-ups for many people reaches it quickly: add people you already know with audiences.import_contacts instead. Past the limit the call raises OpenEmail::RateLimitError. Pass the page the form was on as oe_source:, leave out oe_started, and send oe_website empty or not at all.
A 422 from subscribe is invalid_form_submission, raised as OpenEmail::ValidationError, and the error’s fields lists each answer that is missing or not valid as a Hash with key and error, with reasons such as required, email and option. OpenEmail::FORM_FIELD_ERRORS names every reason. The gem runs on a server. A browser posts the answers to the form’s subscribeUrl itself, as a JSON body or with an Accept: application/json header, and gets JSON back from any origin. Without either it gets a 303 redirect to the hosted page.
Response: a form
list returns one OpenEmail::Page of forms, newest first, without document and settings, and list_all and iterate walk every page. get, create, update, publish, pause, resume and duplicate return the whole form as a Hash, which adds document, publishedDocument, settings, audiences, senderIssue and senderProblem.
idString- The durable handle, `frm_` followed by 24 hex characters.
statusString- `draft` until the first publish, then `live` while it takes sign-ups and `paused` while it does not. A form never goes back to `draft`. `OpenEmail::FORM_STATUSES` names the three.
urlString- The hosted page of the published form, to share as a link.
subscribeUrlString- Where a plain HTML form, or a script in the browser, posts the answers.
documentHash- The draft: `fields` in order, the `copy` around them and the `style`.
publishedDocumentHash or nil- What visitors see now, or nil until the first publish.
settingsHash- Where sign-ups go and what happens after one: `audienceIds`, `doubleOptIn`, `senderAddress`, the confirmation email, `successAction`, `redirectUrl` and `notifyAddresses`.
hasUnpublishedChangesBoolean- True when the draft differs from what visitors see. Always false before the first publish.
senderIssueString or nil- Why a double opt-in form cannot send its confirmation emails right now: `missing`, `not_sendable` or `not_allowed`. It is nil when it can. `OpenEmail::FORM_SENDER_ISSUES` names the three.
statsHash- `views`, `submissions`, `added`, `pending` and `lastSubmittedAt`, counted at the moment of the read.
Submissions
list_submissions pages newest first, with q: to search email addresses and status: for pending or added, and list_all_submissions and iterate_submissions walk every page. OpenEmail::FORM_SUBMISSION_STATUSES names the two statuses. Each submission is a Hash that keeps the answers as they were sent, labels included, so it still reads right after the form changes.
resend_confirmation returns the submission with confirmationSent. It is false when nothing went out: one address gets one confirmation per form every ten minutes and five a day across the workspace, and an added submission gets none. expired marks a pending sign-up whose latest link has run out.