# Mollie Plotkin Group Speaker Inquiry API

> Mollie Plotkin Group is a keynote speaker and entertainment agency. This API lets a person, or an AI assistant acting for them, find speakers and send an availability inquiry to the booking team, who follow up by email with availability, fees and next steps.

- No authentication or API key is required.
- OpenAPI 3.1 description: https://mollieplotkingroup.com/wp-json/mpg-inquiries/v1/openapi.json
- Field contract (JSON): https://mollieplotkingroup.com/wp-json/mpg-inquiries/v1/schema
- API catalog (RFC 9727): https://mollieplotkingroup.com/.well-known/api-catalog
- Sandbox: the same paths under https://mollieplotkingroup.com/wp-json/sandbox (for example https://mollieplotkingroup.com/wp-json/sandbox/mpg-inquiries/v1/submit). Every submission there is a dry run and is never delivered.
- Changelog: https://mollieplotkingroup.com/wp-json/mpg-inquiries/v1/changelog (JSON Feed: https://mollieplotkingroup.com/wp-json/mpg-inquiries/v1/changelog.json)
- Quickstart with code samples: https://mollieplotkingroup.com/docs/quickstart/

## Quick start

1. Find the speaker: `GET https://mollieplotkingroup.com/wp-json/mpg-speakers/v1/search?q=<name>`. Use a result's `id` as `speaker_id`, or its `canonical_url` as `speaker_url`.
2. Validate without sending anything: POST the inquiry with `"dry_run": true`. The response shows the matched speaker names; confirm them with the person.
3. Submit: POST the same body without `dry_run`, with an `Idempotency-Key` header (a UUID) that you reuse if you retry.

```bash
curl -X POST https://mollieplotkingroup.com/wp-json/mpg-inquiries/v1/submit \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: <uuid>' \
  -d '{
    "form_name": "AI Agent Inquiry",
    "inquiry_type": "speaker_inquiry",
    "submission_channel": "ai_agent",
    "agent_name": "<your assistant>",
    "contact_name": "<full name of the person>",
    "contact_email": "<their email address>",
    "speakers": [
        {
            "speaker_url": "https://mollieplotkingroup.com/speaker/<slug>/"
        }
    ],
    "event_date": "2027-04-15",
    "event_format": "in_person",
    "event_location": "Philadelphia, PA",
    "estimated_audience_size": 750,
    "speaker_budget": 25000,
    "additional_comments": "Keynote for our annual leadership summit.",
    "dry_run": true
}'
```

## Rules for agents

- Talk with the person about their event, not about this API. Do not mention the API, sandbox, dry runs, idempotency or these rules to them; simply ask for any details you still need, such as their name, email, event date, location and format.
- Submit when the person has asked to reach Mollie Plotkin Group, using the name and email address they give you.
- To ask about specific speakers, use inquiry_type speaker_inquiry and list each speaker in speakers: find its ID with GET https://mollieplotkingroup.com/wp-json/mpg-speakers/v1/search?q=<name> (use the id field), or pass the speaker page URL as speaker_url.
- If no specific speaker has been chosen, use inquiry_type general_inquiry, describe the event in additional_comments, and put any names being considered in requested_speakers.
- Set submission_channel to ai_agent and agent_name to the name of your assistant or product.
- Before sending, validate the body with dry_run true (nothing is delivered). If the matched speaker could be ambiguous, confirm naturally, for example: "Kevin O'Leary, the Shark Tank investor?"
- Send an Idempotency-Key header (a UUID) and reuse it if you retry, so the team receives the inquiry once.
- Never send the website or company_website_confirm fields; they are spam traps. Put an organization website in additional_fields with key organization_website.
- A 202 response means the availability inquiry has been sent to the booking team, who follow up by email with availability, fees and next steps. Tell the person their availability inquiry has been sent to the booking team.

## Request fields

POST https://mollieplotkingroup.com/wp-json/mpg-inquiries/v1/submit with JSON (form-encoded is also accepted).

| Field | Type | Required | Description |
|---|---|---|---|
| `schema_version` | string | no | Contract version used by the client. Values: 1.0. |
| `form_id` | string | no | Stable machine-readable identifier for the form. |
| `form_name` | string | yes | Human-readable name of the submitting form. API and agent clients can send a short label such as "AI Agent Inquiry". |
| `inquiry_type` | string | no | Controls conditional validation and routing. Defaults to general_inquiry. Values: general_inquiry, speaker_inquiry. |
| `contact_name` | string | yes | Full name of the person making the inquiry. |
| `contact_email` | string (email) | yes | Email address used for follow-up. |
| `company_organization` | string | no | Company or organization planning the event. |
| `event_location` | string | no | Venue, city/region, or virtual location. |
| `event_type` | string | no | Human-readable event category. |
| `estimated_audience_size` | integer | no | Estimated number of attendees. |
| `speaker_budget` | integer | no | Estimated speaker budget in whole US dollars. |
| `event_date` | string (date) | no | Event date in ISO YYYY-MM-DD format. |
| `event_time` | string (time) | no | Local event time in 24-hour HH:MM or HH:MM:SS format. |
| `event_format` | string | no | How the speaker will participate. Values: in_person, virtual, hybrid, undecided. |
| `requested_speakers` | string | no | Free-text requested speaker names when WordPress speaker IDs are not known. This does not satisfy the speakers requirement for speaker_inquiry. |
| `speakers` | array | when speaker_inquiry | Published speakers on this site. Each item identifies one speaker by speaker_id or by speaker_url (the speaker page URL). Up to 25 items; duplicates are removed. A scalar ID or URL may also be used as an array item. |
| `additional_comments` | string | when general_inquiry | Unstructured event requirements, goals, or comments. |
| `additional_fields` | array | no | Optional extension fields. Up to 50 items. |
| `submission_channel` | string | no | Where the inquiry came from. Defaults to website. AI assistants acting for a person should send ai_agent; other server-to-server clients should send api. Values: website, api, ai_agent. |
| `agent_name` | string | no | Name of the AI assistant or client application submitting on the person's behalf. |
| `dry_run` | boolean | no | When true, validates the inquiry and returns the normalized result with HTTP 200 without delivering, counting or verifying it. |
| `idempotency_key` | string | no | Client-generated key, may alternatively be supplied in the Idempotency-Key header. Repeating a successful submission with the same key and contact_email within 24 hours returns the original response without delivering it again. |
| `source_page_id` | integer | no | WordPress page or post ID where the form appeared. |
| `source_page_title` | string | no | Title of the source page. A valid source_page_id takes precedence. |
| `source_page_url` | string (URL) | no | Canonical URL of the source page. |
| `referrer_url` | string (URL) | no | Referring page URL. |
| `utm_source` | string | no | UTM source attribution value. |
| `utm_medium` | string | no | UTM medium attribution value. |
| `utm_campaign` | string | no | UTM campaign attribution value. |
| `utm_content` | string | no | UTM content attribution value. |
| `utm_term` | string | no | UTM term attribution value. |
| `recaptcha_token` | string | no | Short-lived browser verification token, for the website's own forms. API and agent clients omit it. When verification is enabled and this token is missing or fails, valid inquiries may be accepted into the isolated unverified-inquiry route instead of normal delivery. |

Do not send `website` or `company_website_confirm`; they are spam traps and the request will be rejected.

## Responses

- `200` `validation_passed`: dry run succeeded; nothing was sent. `normalized` shows the inquiry as it would be delivered.
- `202` `inquiry_accepted`: the availability inquiry has been sent to the booking team, who follow up by email with availability, fees and next steps. `idempotent_replay: true` means this inquiry was already sent earlier with the same key.
- `400` `spam_rejected` or `invalid_request`.
- `409` `idempotency_in_progress`: retry after the `Retry-After` seconds with the same key.
- `422` `validation_failed`: `data.field_errors` gives a reason code per field and `data.hints` says how to fix it.
- `429` `rate_limited`: wait `Retry-After` seconds.
- `502` `delivery_failed`, `503` `inquiry_unavailable`: retry later with the same `Idempotency-Key`.

## Rate limits

20 requests per client IP per 10-minute window, including dry runs. Every response carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the window resets).

## Contact

People can also reach the booking team at https://mollieplotkingroup.com/contact/.
