{"openapi":"3.1.0","info":{"title":"Hi, Moose API","version":"1.2.1","summary":"Read the AI search visibility data Hi, Moose has stored for your projects.","description":"The Hi, Moose API is a read-only REST API for developers who build reporting or dashboard apps on top of Hi, Moose visibility data without using an AI agent.\n\nRead endpoints return stored results. With the tracking:write permission a key can create projects and manage prompts, engines and the schedule. With the runs:execute permission it can start a run, which spends the account allowance on cloud engines and uses the host computer for local-fetch engines.\n\nAuthenticate with a personal API key created in Hi, Moose under Settings, API keys. Send it as a Bearer token. Keys are scoped to projects and can be revoked at any time.\n\nAll times are UTC. Dates are YYYY-MM-DD. Lists are paginated with an opaque cursor. Errors follow RFC 9457 Problem Details.\n\n\nThe API is available on paid plans (managed and BYOK). Free accounts get 403 plan_required. Only the account owner can create keys. There are no CORS headers: call the API from your own server, never from a browser page.\n\nWebhooks: register an https endpoint per project and Hi, Moose posts a signed JSON event when a run completes or fails, with retries over 24 hours.\n","termsOfService":"https://himoose.com/terms/","contact":{"name":"Hi, Moose support","url":"https://himoose.com/docs/integrations/developer-api/","email":"support@himoose.com"}},"servers":[{"url":"https://api.himoose.com/v1"}],"security":[{"apiKey":[]}],"tags":[{"name":"Account","description":"Who the key belongs to and what it can read."},{"name":"Projects","description":"Projects the key can read and what each one tracks."},{"name":"Setup","description":"Engines, topics, prompts and tracked competitors for a project."},{"name":"Results","description":"Runs and the stored answers from each engine."},{"name":"Stats","description":"Mention and citation rates over time, ready for charts."},{"name":"Tracking","description":"Create projects and manage what Hi, Moose tracks. Needs the tracking:write permission."},{"name":"Runs","description":"Start visibility runs and follow them. Needs the runs:execute permission."},{"name":"Webhooks","description":"Get a signed HTTP call when a run finishes. Managing webhooks needs the tracking:write permission."}],"paths":{"/me":{"get":{"tags":["Account"],"operationId":"getMe","summary":"Describe the API key","responses":{"200":{"description":"The key and its access.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"},"RateLimit":{"$ref":"#/components/headers/RateLimit"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Returns the key's label, permissions, expiry, the account plan and the project ids the key can read. A good first call to check a key."}},"/projects":{"get":{"tags":["Projects"],"operationId":"listProjects","summary":"List projects the key can read","parameters":[{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"A page of projects.","content":{"application/json":{"schema":{"type":"object","required":["data","nextCursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"nextCursor":{"$ref":"#/components/schemas/NextCursor"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Lists the projects the key may read, newest first, with a summary of what each one tracks and when it last ran."},"post":{"tags":["Tracking"],"operationId":"createProject","summary":"Create a project","description":"Creates a project with a name and site address. The site crawl is not started; the host computer turns on the weekly scheduled crawl so it happens later. If another project on the account has a host device, the new project uses the same one. Brand Truth is not required.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCreate"}}}},"responses":{"201":{"description":"The new project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectWithHost"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}":{"get":{"tags":["Projects"],"operationId":"getProject","summary":"Get one project","parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"The project.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Returns one project with its tracking summary."},"patch":{"tags":["Tracking"],"operationId":"updateProject","summary":"Change a project name, site address, brand terms or domains","parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUpdate"}}}},"responses":{"200":{"description":"The resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectWithHost"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Changes only the fields sent. Brand terms and brand domains replace the whole list when sent. The site crawl is not touched."}},"/projects/{projectId}/engines":{"get":{"tags":["Setup"],"operationId":"listEngines","summary":"List the engines this project tracks","description":"Engines are the AI answer engines Hi, Moose asks, such as ChatGPT, Gemini, Perplexity, Grok, Claude and Google AI Mode. The id is stable and is what the engine filter takes elsewhere.","parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"The engine list. Not paginated; there are at most a few dozen.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Engine"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}/topics":{"get":{"tags":["Setup"],"operationId":"listTopics","summary":"List the topics that group the tracked prompts","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"A page of topics.","content":{"application/json":{"schema":{"type":"object","required":["data","nextCursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Topic"}},"nextCursor":{"$ref":"#/components/schemas/NextCursor"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Lists the topics that group the tracked prompts, with a prompt count each. Topic ids are the values to pass as topicId."}},"/projects/{projectId}/prompts":{"get":{"tags":["Setup"],"operationId":"listPrompts","summary":"List the tracked prompts","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/TopicId"},{"name":"status","in":"query","description":"Only prompts with this status. Default is all.","schema":{"type":"string","enum":["active","paused"]}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"A page of prompts.","content":{"application/json":{"schema":{"type":"object","required":["data","nextCursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Prompt"}},"nextCursor":{"$ref":"#/components/schemas/NextCursor"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Lists the tracked prompts, newest first, with their topics, engines and status."},"post":{"tags":["Tracking"],"operationId":"createPrompt","summary":"Add a tracked prompt","description":"Engine ids default to the project tracking engines. Duplicate text is refused with 409.","parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromptCreate"}}}},"responses":{"201":{"description":"The new prompt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Prompt"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}/competitors":{"get":{"tags":["Setup"],"operationId":"listCompetitors","summary":"List the tracked competitors","description":"The competitor brands Hi, Moose looks for in every answer. Competitor stats use these names.","parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"The competitor list. Not paginated; at most 50.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Competitor"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"put":{"tags":["Tracking"],"operationId":"replaceCompetitors","summary":"Replace the tracked competitor list","description":"Replaces the whole list. At most 50. Names are matched case-insensitively.","parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","maxItems":50,"items":{"$ref":"#/components/schemas/CompetitorInput"}}}}},"responses":{"200":{"description":"The saved list.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Competitor"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}/runs":{"get":{"tags":["Results"],"operationId":"listRuns","summary":"List visibility runs","description":"A run is one pass over the tracked prompts on the tracked engines. Newest first.","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/From"},{"$ref":"#/components/parameters/To"},{"name":"status","in":"query","schema":{"type":"string","enum":["completed","running","failed","canceled"]},"description":"Only runs with this status."},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"A page of runs.","content":{"application/json":{"schema":{"type":"object","required":["data","nextCursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Run"}},"nextCursor":{"$ref":"#/components/schemas/NextCursor"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}/answers":{"get":{"tags":["Results"],"operationId":"listAnswers","summary":"List stored answers","description":"One answer is one engine's reply to one prompt on one date. Newest first. This list carries the excerpt, the mention and citation flags, the position, the sentiment, the competitors seen and the source URLs. The full answer text is on the detail endpoint.\n\nDate range defaults to the last 30 days. The widest range per request is 366 days.\n","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/From"},{"$ref":"#/components/parameters/To"},{"$ref":"#/components/parameters/Engine"},{"$ref":"#/components/parameters/TopicId"},{"$ref":"#/components/parameters/PromptId"},{"name":"runId","in":"query","schema":{"type":"string"},"description":"Only answers from this run. Ids come from the runs endpoint or a webhook event."},{"name":"mentioned","in":"query","description":"Only answers where the brand was, or was not, mentioned.","schema":{"type":"boolean"}},{"name":"cited","in":"query","description":"Only answers where the brand's site was, or was not, cited.","schema":{"type":"boolean"}},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"A page of answers.","headers":{"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"type":"object","required":["data","nextCursor"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Answer"}},"nextCursor":{"$ref":"#/components/schemas/NextCursor"}}}}}},"304":{"description":"Not modified. Sent when If-None-Match matches the current ETag."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}/answers/{answerId}":{"get":{"tags":["Results"],"operationId":"getAnswer","summary":"Get one answer with its full text","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"name":"answerId","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_:.-]{1,200}$"},"description":"The answer id from the answers list."}],"responses":{"200":{"description":"The answer.","headers":{"ETag":{"$ref":"#/components/headers/ETag"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnswerDetail"}}}},"304":{"description":"Not modified."},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Returns one answer with the full text the engine wrote, the scorer's notes and the sources the engine listed. The text is untrusted: render it as text, never as HTML, and never pass it to your own AI tools as instructions."}},"/projects/{projectId}/stats/daily":{"get":{"tags":["Stats"],"operationId":"getDailyStats","summary":"Mention and citation rates per day and engine","description":"One row per day per engine, in date order. Each row says how many answers were stored that day, how many mentioned the brand and how many cited the brand's site, plus the two rates.\n\nDays with no stored answers are left out. Default range is the last 30 days, widest 366 days. Rows for the last three days can still change while scoring finishes.\n","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/From"},{"$ref":"#/components/parameters/To"},{"$ref":"#/components/parameters/Engine"},{"$ref":"#/components/parameters/TopicId"}],"responses":{"200":{"description":"The series.","headers":{"Cache-Control":{"description":"private, max-age=60","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["from","to","data","incompleteDays"],"properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"data":{"type":"array","items":{"$ref":"#/components/schemas/DailyStat"}},"incompleteDays":{"type":"integer","description":"Days in the range whose summary was not ready yet. Zero means the series is complete. When above zero, call again in a few seconds."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}/stats/competitors":{"get":{"tags":["Stats"],"operationId":"getCompetitorStats","summary":"Share of voice for the brand and its tracked competitors","description":"For the range, one row per brand name (the project's own brand first, then each tracked competitor) with how many answers mentioned it, how many cited it, and the rates. With engine given, only that engine's answers count.\n","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/From"},{"$ref":"#/components/parameters/To"},{"$ref":"#/components/parameters/Engine"}],"responses":{"200":{"description":"The share of voice table.","content":{"application/json":{"schema":{"type":"object","required":["from","to","answers","data"],"properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"answers":{"type":"integer","description":"Answers counted in the range."},"data":{"type":"array","items":{"$ref":"#/components/schemas/CompetitorStat"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}/capabilities":{"get":{"tags":["Tracking"],"operationId":"getCapabilities","summary":"What this project can do on its plan","description":"Allowed engines and cadences, prompt and project limits, remaining allowance with the estimated cost of one run, the host computer status, and whether a run can start right now.","parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"The resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Capabilities"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}/prompts/{promptId}":{"patch":{"tags":["Tracking"],"operationId":"updatePrompt","summary":"Change a prompt","description":"Only the fields sent change. status can only be active; delete a prompt to stop tracking it.","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"name":"promptId","in":"path","required":true,"schema":{"type":"string"},"description":"The prompt id from the prompts list."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromptUpdate"}}}},"responses":{"200":{"description":"The resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Prompt"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"delete":{"tags":["Tracking"],"operationId":"deletePrompt","summary":"Stop tracking a prompt","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"name":"promptId","in":"path","required":true,"schema":{"type":"string"},"description":"The prompt id from the prompts list."}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Removes the prompt from tracking. Stored answers for it are kept and stay readable on the answers endpoint."}},"/projects/{projectId}/tracking":{"put":{"tags":["Tracking"],"operationId":"updateTracking","summary":"Set engines, schedule and samples","description":"Only the fields sent change. engineIds sets the default engines for new prompts. Existing prompts keep their own engines unless applyEnginesToPrompts is true. The host computer picks the new schedule up within a minute while it is open, or when it next opens.","parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackingUpdate"}}}},"responses":{"200":{"description":"The resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tracking"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}/run-requests":{"post":{"tags":["Runs"],"operationId":"createRunRequest","summary":"Start a visibility run","description":"Checks the allowance first and refuses with 409 insufficient_allowance when the estimate is above the remaining balance. One request at a time per project, at most 24 per project per day. Projects whose tracked engines are all cloud engines run in the cloud at once. Any local-fetch engine means the run is handed to the host computer; if that computer is off the request is accepted with a warning and waits up to 24 hours. Send an Idempotency-Key header to make retries safe for 24 hours.","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":128},"description":"Any string up to 128 characters that identifies this attempt. A retry with the same key within 24 hours returns the earlier request instead of starting another run."}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunRequestCreate"}}}},"responses":{"200":{"description":"Replayed from an earlier request with the same Idempotency-Key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunRequest"}}}},"202":{"description":"Accepted. Poll the Location header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunRequest"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"get":{"tags":["Runs"],"operationId":"listRunRequests","summary":"Recent run requests","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Newest first.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RunRequest"}},"nextCursor":{"$ref":"#/components/schemas/NextCursor"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Lists run requests made through the API, newest first, with their current status."}},"/projects/{projectId}/run-requests/{requestId}":{"get":{"tags":["Runs"],"operationId":"getRunRequest","summary":"Follow a run request","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"name":"requestId","in":"path","required":true,"schema":{"type":"string"},"description":"The run request id from the 202 response or its Location header."}],"responses":{"200":{"description":"The resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunRequest"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Returns one run request with its current status, run ids once completed, and the host computer state for host runs. Poll it about once a minute."}},"/projects/{projectId}/webhooks":{"post":{"tags":["Webhooks"],"operationId":"createWebhook","summary":"Register a webhook","description":"Up to 5 per project. The url must be public https. The signing secret is returned once in this response and never again. Default events are run.completed and run.failed.","parameters":[{"$ref":"#/components/parameters/ProjectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreate"}}}},"responses":{"201":{"description":"The webhook with its signing secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookWithSecret"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}}},"get":{"tags":["Webhooks"],"operationId":"listWebhooks","summary":"List webhooks","parameters":[{"$ref":"#/components/parameters/ProjectId"}],"responses":{"200":{"description":"The webhooks, without secrets.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Lists the project's webhooks without their signing secrets."}},"/projects/{projectId}/webhooks/{webhookId}":{"delete":{"tags":["Webhooks"],"operationId":"deleteWebhook","summary":"Delete a webhook","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"The webhook id from the webhooks list."}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Removes the webhook. Pending deliveries are dropped."}},"/projects/{projectId}/webhooks/{webhookId}/test":{"post":{"tags":["Webhooks"],"operationId":"testWebhook","summary":"Send a ping event now","description":"Posts a signed ping event so you can check your endpoint and signature code. The response shows the first attempt.","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"The webhook id from the webhooks list."}],"responses":{"200":{"description":"The ping delivery after its first attempt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDelivery"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}}}},"/projects/{projectId}/webhooks/{webhookId}/deliveries":{"get":{"tags":["Webhooks"],"operationId":"listWebhookDeliveries","summary":"Recent deliveries and their attempts","parameters":[{"$ref":"#/components/parameters/ProjectId"},{"name":"webhookId","in":"path","required":true,"schema":{"type":"string"},"description":"The webhook id from the webhooks list."}],"responses":{"200":{"description":"Newest first, up to 50.","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"nextCursor":{"$ref":"#/components/schemas/NextCursor"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"429":{"$ref":"#/components/responses/TooManyRequests"}},"description":"Lists the last 50 deliveries for the webhook, newest first, each with every attempt, its HTTP status and error."}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"Personal API key from Settings, API keys. Starts with hmk_live_."}},"parameters":{"ProjectId":{"name":"projectId","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9]{1,64}$"},"description":"The project id from the projects endpoint."},"Cursor":{"name":"cursor","in":"query","description":"The nextCursor value from the previous page. Opaque.","schema":{"type":"string","maxLength":512}},"Limit":{"name":"limit","in":"query","description":"Rows per page. Default 50, at most 200.","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},"From":{"name":"from","in":"query","description":"First day to include, YYYY-MM-DD, UTC.","schema":{"type":"string","format":"date"}},"To":{"name":"to","in":"query","description":"Last day to include, YYYY-MM-DD, UTC. Defaults to today.","schema":{"type":"string","format":"date"}},"Engine":{"name":"engine","in":"query","description":"Only this engine. Repeat the parameter for several engines. Values come from the engines endpoint.","style":"form","explode":true,"schema":{"type":"array","items":{"type":"string","maxLength":60}}},"TopicId":{"name":"topicId","in":"query","schema":{"type":"string","maxLength":200},"description":"Only prompts or answers in this topic. Ids come from the topics endpoint."},"PromptId":{"name":"promptId","in":"query","schema":{"type":"string","maxLength":200},"description":"Only answers to this prompt. Ids come from the prompts endpoint."}},"headers":{"X-Request-Id":{"description":"Unique id for this request. Quote it when you contact support.","schema":{"type":"string"}},"RateLimit":{"description":"Remaining budget in the current window, per IETF draft-ietf-httpapi-ratelimit-headers.","schema":{"type":"string"},"example":"limit=300, remaining=297, reset=42"},"ETag":{"description":"Hash of the response body. Send it back in If-None-Match to get a 304 when nothing changed.","schema":{"type":"string"}}},"responses":{"BadRequest":{"description":"A parameter is missing or malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://himoose.com/docs/integrations/developer-api/errors-and-limits/#errors","title":"Bad request","status":400,"detail":"from must be a date in YYYY-MM-DD form.","code":"invalid_parameter","instance":"/v1/projects/abc123/answers","requestId":"7f4c0d1a2b"}}}},"Unauthorized":{"description":"The key is missing, malformed, revoked or expired.","headers":{"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"Hi, Moose API\""}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://himoose.com/docs/integrations/developer-api/errors-and-limits/#errors","title":"Unauthorized","status":401,"detail":"The API key is not valid. Create a new one in Hi, Moose under Settings, API keys.","code":"invalid_key","instance":"/v1/me","requestId":"7f4c0d1a2b"}}}},"NotFound":{"description":"No such resource, or the key cannot read it. The two cases are not told apart.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://himoose.com/docs/integrations/developer-api/errors-and-limits/#errors","title":"Not found","status":404,"detail":"No project with that id is readable with this key.","code":"not_found","instance":"/v1/projects/abc123","requestId":"7f4c0d1a2b"}}}},"TooManyRequests":{"description":"The per-minute or per-day limit was reached.","headers":{"Retry-After":{"description":"Seconds to wait.","schema":{"type":"integer"}},"RateLimit":{"$ref":"#/components/headers/RateLimit"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://himoose.com/docs/integrations/developer-api/errors-and-limits/#rate-limits","title":"Too many requests","status":429,"detail":"This key has used its 300 requests for the current minute.","code":"rate_limited","instance":"/v1/projects/abc123/answers","requestId":"7f4c0d1a2b"}}}},"Forbidden":{"description":"The account plan does not include the API, or the key lacks the scope.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://himoose.com/docs/integrations/developer-api/errors-and-limits/#errors","title":"Forbidden","status":403,"detail":"The Hi, Moose API is available on paid plans. Upgrade in Hi, Moose under Settings, Usage.","code":"plan_required","instance":"/v1/me","requestId":"7f4c0d1a2b"}}}},"Conflict":{"description":"The request is valid but cannot be done right now. The code says why.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://himoose.com/docs/integrations/developer-api/errors-and-limits/#errors","title":"Conflict","status":409,"detail":"This run needs about 42000 allowance units and the account has 12000 left this period.","code":"insufficient_allowance","instance":"/v1/projects/abc123/run-requests","requestId":"7f4c0d1a2b","estimatedUnits":42000,"remainingUnits":12000}}}}},"schemas":{"Problem":{"type":"object","description":"RFC 9457 Problem Details with two extensions, code and requestId.","required":["type","title","status","code","requestId"],"properties":{"type":{"type":"string","format":"uri","description":"Link to the docs section for this kind of error."},"title":{"type":"string","description":"Short name of the HTTP status."},"status":{"type":"integer","description":"The HTTP status code, repeated in the body."},"detail":{"type":"string","description":"What went wrong and, where possible, what to change."},"instance":{"type":"string","description":"The request path this error is about."},"code":{"type":"string","description":"Stable machine-readable reason.","enum":["byok_not_supported","daily_run_limit","host_required","insufficient_allowance","insufficient_scope","internal","invalid_key","invalid_parameter","key_expired","key_revoked","method_not_allowed","no_prompts","not_found","plan_limit","plan_required","range_too_wide","rate_limited","run_in_progress","unsupported_filter_combination"]},"requestId":{"type":"string","description":"Unique id for the request. Quote it when you contact support."}}},"NextCursor":{"type":["string","null"],"description":"Pass as cursor to get the next page. Null on the last page."},"Me":{"type":"object","required":["keyId","label","scopes","createdAt","expiresAt","account","projects"],"properties":{"keyId":{"type":"string","description":"Short public id of the key, also shown in Settings."},"label":{"type":"string","description":"The label given to the key when it was created."},"scopes":{"type":"array","items":{"type":"string","enum":["visibility:read","tracking:write","runs:execute"]},"description":"The key's permissions."},"createdAt":{"type":"string","format":"date-time","description":"When the key was created."},"expiresAt":{"type":["string","null"],"format":"date-time","description":"When the key stops working, or null when it never expires."},"account":{"type":"object","required":["plan"],"properties":{"plan":{"type":"string","description":"The plan code, for example free or premium."}},"description":"The account the key belongs to."},"projects":{"type":"array","description":"Project ids the key can read.","items":{"type":"string"}}}},"Project":{"type":"object","required":["id","name","websiteUrl","visibility"],"properties":{"id":{"type":"string","description":"The project id used in every project endpoint."},"name":{"type":"string","description":"The project name as shown in Hi, Moose."},"websiteUrl":{"type":["string","null"],"format":"uri","description":"The site address the project tracks."},"visibility":{"type":"object","required":["trackedPrompts","engines","latestRunAt","firstAnswerDate","latestAnswerDate"],"properties":{"trackedPrompts":{"type":"integer","description":"How many prompts are tracked."},"engines":{"type":"array","items":{"type":"string"},"description":"Ids of the engines the project tracks by default."},"latestRunAt":{"type":["string","null"],"format":"date-time","description":"When the latest run finished, or null when no run has completed yet."},"firstAnswerDate":{"type":["string","null"],"format":"date","description":"The first day with stored answers, or null."},"latestAnswerDate":{"type":["string","null"],"format":"date","description":"The most recent day with stored answers, or null."}},"description":"A summary of what the project tracks and when it last ran."}}},"Engine":{"type":"object","required":["id","label","tracked"],"properties":{"id":{"type":"string","description":"Stable engine id, for example chatgpt, gemini, perplexity, grok, claude, google-ai-mode. Local-fetch variants end in -local-fetch.","examples":["chatgpt","gemini-local-fetch"]},"label":{"type":"string","description":"Display name."},"tracked":{"type":"boolean","description":"Whether new runs ask this engine. Engines with stored answers but no longer tracked are listed with false."}}},"Topic":{"type":"object","required":["id","label","promptCount"],"properties":{"id":{"type":"string","description":"The topic id to pass as topicId in filters and on prompts."},"label":{"type":"string","description":"The topic name as shown in Hi, Moose."},"promptCount":{"type":"integer","description":"How many tracked prompts belong to this topic."}}},"Prompt":{"type":"object","required":["id","text","topicIds","engineIds","status","createdAt"],"properties":{"id":{"type":"string","description":"The prompt id used in the prompt endpoints and the promptId filter."},"text":{"type":"string","description":"The question the engines are asked."},"topicIds":{"type":"array","items":{"type":"string"},"description":"Ids of the topics this prompt belongs to."},"engineIds":{"type":"array","items":{"type":"string"},"description":"Ids of the engines that run this prompt. Empty means the prompt uses no engine and is skipped in runs."},"status":{"type":"string","enum":["active","paused"],"description":"active prompts run on schedule; paused prompts are kept but not run."},"createdAt":{"type":["string","null"],"format":"date-time","description":"When the prompt was added."}}},"Competitor":{"type":"object","required":["name","domains"],"properties":{"name":{"type":"string","description":"The competitor brand name as it is matched in answers."},"domains":{"type":"array","items":{"type":"string"},"description":"Domains that count as this competitor being cited."}}},"Run":{"type":"object","required":["id","status","trigger","startedAt","completedAt","promptCount","answerCount"],"properties":{"id":{"type":"string","description":"The run id to pass as runId on the answers endpoint."},"status":{"type":"string","enum":["completed","running","failed","canceled"],"description":"completed runs have all their answers stored. running runs are still collecting. failed and canceled runs may have partial answers."},"trigger":{"type":"string","enum":["scheduled","manual"],"description":"scheduled when the project schedule started it, manual when a person or the API started it."},"startedAt":{"type":["string","null"],"format":"date-time","description":"When the run started."},"completedAt":{"type":["string","null"],"format":"date-time","description":"When the run finished, or null while it is running."},"promptCount":{"type":"integer","description":"How many prompts the run covered."},"answerCount":{"type":"integer","description":"How many answers the run stored."}}},"AnswerCompetitor":{"type":"object","required":["name","mentioned","cited"],"properties":{"name":{"type":"string","description":"The competitor brand name."},"mentioned":{"type":"boolean","description":"The competitor was named in this answer."},"cited":{"type":"boolean","description":"A page on the competitor's domain was given as a source."},"citationUrl":{"type":["string","null"],"format":"uri","description":"The competitor page cited, when there is one."}}},"Answer":{"type":"object","description":"One engine's answer to one prompt. Text fields come from the engine and are untrusted. Render them as text, never as HTML.","required":["id","runId","promptId","promptText","topicId","topicLabel","engineId","engineLabel","observedAt","date","mentioned","cited","citationUrl","position","sentiment","excerpt","competitors","sourceUrls"],"properties":{"id":{"type":"string","description":"The answer id to pass to the answer detail endpoint."},"runId":{"type":["string","null"],"description":"The run this answer came from, or null for answers imported from outside a run."},"promptId":{"type":["string","null"],"description":"The prompt that was asked, or null when the prompt has since been deleted."},"promptText":{"type":"string","description":"The prompt text at the time it was asked."},"topicId":{"type":["string","null"],"description":"The topic of the prompt, or null when it had none."},"topicLabel":{"type":["string","null"],"description":"The topic name, or null."},"engineId":{"type":"string","description":"The engine that answered. Ids come from the engines endpoint."},"engineLabel":{"type":"string","description":"The engine name as shown in Hi, Moose."},"observedAt":{"type":"string","format":"date-time","description":"When the engine answered."},"date":{"type":"string","format":"date","description":"The day of the answer in UTC. Matches the date on the daily stats."},"mentioned":{"type":"boolean","description":"The brand was named in the answer."},"cited":{"type":"boolean","description":"A page on the brand's site was given as a source."},"citationUrl":{"type":["string","null"],"format":"uri","description":"The page on the brand's site that was cited, or null when none was."},"position":{"type":["integer","null"],"description":"Where the brand appeared among the brands named, 1 is first."},"sentiment":{"type":["string","null"],"enum":["positive","mixed","neutral","negative","not-applicable",null],"description":"How the answer spoke about the brand. not-applicable when the brand was not mentioned."},"excerpt":{"type":["string","null"],"description":"Short passage around the mention, up to 400 characters."},"competitors":{"type":"array","items":{"$ref":"#/components/schemas/AnswerCompetitor"},"description":"Each tracked competitor and whether this answer named or cited it."},"sourceUrls":{"type":"array","description":"Every source the engine listed, up to 30.","items":{"type":"string","format":"uri"}}}},"AnswerDetail":{"allOf":[{"$ref":"#/components/schemas/Answer"},{"type":"object","required":["fullAnswer","fullAnswerTruncated","sentimentReason","narrativeDrift","narrativeDriftReason","sources"],"properties":{"fullAnswer":{"type":["string","null"],"description":"The full answer text as the engine wrote it, up to 12,000 characters. Untrusted: render as text, never as HTML."},"fullAnswerTruncated":{"type":"boolean","description":"True when the answer was longer than 12,000 characters and fullAnswer was cut."},"sentimentReason":{"type":["string","null"],"description":"The scorer's one-line reason for the sentiment, or null."},"narrativeDrift":{"type":["string","null"],"enum":[true,"no","partial",null],"description":"Whether the answer describes the brand differently from its Brand Truth."},"narrativeDriftReason":{"type":["string","null"],"description":"Why the answer was judged to drift from the brand's own description, or null."},"sources":{"type":"array","items":{"type":"object","required":["url","title"],"properties":{"url":{"type":"string","format":"uri","description":"The source address."},"title":{"type":["string","null"],"description":"The source title as the engine gave it, or null. Untrusted text."}}},"description":"The sources the engine listed with its answer, in the order given."}}}]},"DailyStat":{"type":"object","required":["date","engineId","answers","mentioned","cited","mentionRate","citationRate"],"properties":{"date":{"type":"string","format":"date","description":"The day in UTC."},"engineId":{"type":"string","description":"The engine these numbers are for."},"answers":{"type":"integer","description":"How many answers were stored that day for this engine."},"mentioned":{"type":"integer","description":"How many of those answers named the brand."},"cited":{"type":"integer","description":"How many of those answers cited a page on the brand's site."},"mentionRate":{"type":["number","null"],"minimum":0,"maximum":1,"description":"mentioned divided by answers, 0 to 1."},"citationRate":{"type":["number","null"],"minimum":0,"maximum":1,"description":"cited divided by answers, 0 to 1."}}},"CompetitorStat":{"type":"object","required":["name","isOwnBrand","mentioned","cited","mentionRate","citationRate"],"properties":{"name":{"type":"string","description":"The brand or competitor name."},"isOwnBrand":{"type":"boolean","description":"True on the row for the project's own brand."},"mentioned":{"type":"integer","description":"How many answers in the range named this brand."},"cited":{"type":"integer","description":"How many answers in the range cited this brand's site."},"mentionRate":{"type":["number","null"],"minimum":0,"maximum":1,"description":"mentioned divided by all answers in the range, 0 to 1."},"citationRate":{"type":["number","null"],"minimum":0,"maximum":1,"description":"cited divided by all answers in the range, 0 to 1."}}},"Host":{"type":"object","required":["configured","online","deviceLabel","lastSeenAt"],"properties":{"configured":{"type":"boolean","description":"A host device is chosen for the project in Hi, Moose under Settings, Hi, Moose MCP."},"online":{"type":"boolean","description":"True when the host computer has checked in within the last few minutes."},"deviceLabel":{"type":["string","null"],"description":"The name of the host computer as shown in Hi, Moose."},"lastSeenAt":{"type":["string","null"],"format":"date-time","description":"When the host computer last checked in, or null when it never has."}}},"ProjectCreate":{"type":"object","required":["name","websiteUrl"],"properties":{"name":{"type":"string","maxLength":120,"description":"The project name, shown in Hi, Moose."},"websiteUrl":{"type":"string","format":"uri","description":"The site address to track, with https."},"brandTerms":{"type":"array","maxItems":20,"items":{"type":"string"},"description":"Other names the brand goes by, counted as mentions."},"brandDomains":{"type":"array","maxItems":20,"items":{"type":"string"},"description":"Other domains that count as the brand being cited."}}},"ProjectUpdate":{"type":"object","properties":{"name":{"type":"string","description":"A new project name."},"websiteUrl":{"type":"string","format":"uri","description":"A new site address, with https."},"brandTerms":{"type":"array","items":{"type":"string"},"description":"Replaces the list of other names the brand goes by."},"brandDomains":{"type":"array","items":{"type":"string"},"description":"Replaces the list of other domains that count as the brand being cited."}}},"ProjectWithHost":{"allOf":[{"$ref":"#/components/schemas/Project"},{"type":"object","properties":{"host":{"$ref":"#/components/schemas/Host"},"warning":{"type":["string","null"],"description":"A note about something to finish in Hi, Moose, for example that no host computer could be copied from another project. Null when there is nothing to do."},"brandTerms":{"type":"array","items":{"type":"string"},"description":"Other names the brand goes by, counted as mentions."},"brandDomains":{"type":"array","items":{"type":"string"},"description":"Other domains that count as the brand being cited."}}}]},"CompetitorInput":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":120,"description":"The competitor brand name as it should be matched in answers."},"domain":{"type":["string","null"],"description":"The competitor's site, so citations of it are counted. Optional."}}},"PromptCreate":{"type":"object","required":["text"],"properties":{"text":{"type":"string","maxLength":500,"description":"The question to ask the engines."},"topicIds":{"type":"array","maxItems":20,"items":{"type":"string"},"description":"Topic ids from the topics endpoint. A new id creates the topic."},"engineIds":{"type":"array","items":{"type":"string"},"description":"Defaults to the project tracking engines."}}},"PromptUpdate":{"type":"object","properties":{"text":{"type":"string","maxLength":500,"description":"New text for the prompt."},"topicIds":{"type":"array","items":{"type":"string"},"description":"Replaces the prompt's topics."},"engineIds":{"type":"array","items":{"type":"string"},"description":"Replaces the engines that run this prompt."},"status":{"type":"string","enum":["active"],"description":"Send active to resume a prompt that was paused in Hi, Moose."}}},"TrackingUpdate":{"type":"object","properties":{"engineIds":{"type":"array","minItems":1,"items":{"type":"string"},"description":"The default engines for new prompts. Ids come from the capabilities endpoint."},"applyEnginesToPrompts":{"type":"boolean","default":false,"description":"Send true to also set engineIds on every existing prompt. Left out or false, existing prompts keep their own engines and engineIds only becomes the default for new prompts."},"cadence":{"type":"string","enum":["manual","daily","weekdays","weekly"],"description":"How often the schedule runs. manual turns the schedule off."},"timeOfDay":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","example":"09:00","description":"When the scheduled run starts, as HH:MM in the project timezone."},"weeklyDay":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"description":"The day a weekly schedule runs on."},"timezone":{"type":"string","example":"America/Chicago","description":"An IANA timezone name such as Europe/Berlin, used for timeOfDay."},"samplesPerPrompt":{"type":"integer","minimum":1,"maximum":5,"description":"How many times each prompt is asked per engine in a run. More samples cost more allowance."}}},"Tracking":{"type":"object","required":["engineIds","cadence","timeOfDay","weeklyDay","timezone","samplesPerPrompt","appliedToPrompts","host"],"properties":{"engineIds":{"type":"array","items":{"type":"string"},"description":"The default engines for new prompts."},"cadence":{"type":"string","description":"How often the schedule runs. manual means the schedule is off."},"timeOfDay":{"type":"string","description":"When the scheduled run starts, as HH:MM in the project timezone."},"weeklyDay":{"type":"string","description":"The day a weekly schedule runs on."},"timezone":{"type":"string","description":"The IANA timezone the schedule uses."},"samplesPerPrompt":{"type":"integer","description":"How many times each prompt is asked per engine in a run."},"appliedToPrompts":{"type":"integer","description":"How many prompts had their engines updated."},"host":{"$ref":"#/components/schemas/Host"}}},"Capabilities":{"type":"object","required":["plan","accessMode","engines","cadences","limits","allowance","tracking","host","runs"],"properties":{"plan":{"type":"string","description":"The account plan code."},"accessMode":{"type":"string","enum":["managed","byok-local"],"description":"managed means Hi, Moose runs the cloud engines and tracking settings live in the cloud. byok-local means the account brings its own keys and tracking settings live on the host computer."},"engines":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The engine id to use in engineIds and filters."},"label":{"type":"string","description":"The engine name as shown in Hi, Moose."},"runsOn":{"type":"string","enum":["cloud","host"],"description":"cloud engines run in the cloud; host engines run on the host computer through a browser."}}},"description":"Every engine the plan allows, tracked or not."},"cadences":{"type":"array","items":{"type":"string"},"description":"The schedule cadences the plan allows."},"limits":{"type":"object","properties":{"maxPrompts":{"type":["integer","null"],"description":"The most prompts one project may track."},"maxProjects":{"type":["integer","null"],"description":"The most projects the account may have."},"maxCompetitors":{"type":"integer","description":"The most competitors one project may track."},"maxSamplesPerPrompt":{"type":"integer","description":"The highest samplesPerPrompt the plan allows."},"runRequestsPerDay":{"type":"integer","description":"How many run requests one project may make per day through the API."}},"description":"The plan's limits. Writes over a limit answer 409 plan_limit."},"allowance":{"type":["object","null"],"description":"Null on bring-your-own-key plans.","properties":{"remainingUnits":{"type":["integer","null"],"description":"Allowance units left in the current period, or null when the plan has no period."},"prepaidCreditsRemaining":{"type":"integer","description":"Prepaid credit units that are spent after the period allowance runs out."},"periodEndsAt":{"type":["string","null"],"format":"date-time","description":"When the current allowance period resets, or null."},"estimatedUnitsPerRun":{"type":"integer","description":"The estimated cost of one run with one sample per prompt, from the current prompts and engines."}}},"tracking":{"type":"object","properties":{"engineIds":{"type":"array","items":{"type":"string"},"description":"The default engines for new prompts."},"cadence":{"type":"string","description":"How often the schedule runs."},"timeOfDay":{"type":"string","description":"When the scheduled run starts, HH:MM in the project timezone."},"weeklyDay":{"type":"string","description":"The day a weekly schedule runs on."},"timezone":{"type":"string","description":"The IANA timezone the schedule uses."},"samplesPerPrompt":{"type":"integer","description":"How many times each prompt is asked per engine in a run."},"promptCount":{"type":"integer","description":"How many prompts the project tracks."},"writable":{"type":"boolean","description":"False on bring-your-own-key plans, where tracking settings live on the host computer."}},"description":"The project's current tracking settings."},"host":{"allOf":[{"$ref":"#/components/schemas/Host"},{"type":"object","properties":{"required":{"type":"boolean","description":"True when any tracked engine is a local-fetch engine or the plan is bring-your-own-key."}}}],"description":"The project's host computer, or null when none is chosen."},"runs":{"type":"object","properties":{"canStartCloudRun":{"type":"boolean","description":"True when a cloud run could start now: engines, allowance and no active request."},"canStartHostRun":{"type":"boolean","description":"True when a host run could start now: a host computer is chosen and no request is active."},"hostOnline":{"type":"boolean","description":"True when the host computer is checked in."},"activeRequestId":{"type":["string","null"],"description":"The id of the run request that is queued, waiting or running, or null."},"usedToday":{"type":"integer","description":"How many run requests the project has made today."}},"description":"Whether a run can start right now and why not."}}},"RunRequestCreate":{"type":"object","properties":{"samplesPerPrompt":{"type":"integer","minimum":1,"maximum":5,"default":1,"description":"How many times to ask each prompt per engine in this run. Defaults to 1 and may not exceed the plan limit."}}},"RunRequest":{"type":"object","required":["id","status","mode","createdAt","updatedAt","completedAt","runIds","promptCount","estimatedUnits","warning","error","host"],"properties":{"id":{"type":"string","description":"The run request id. Poll it on the run request endpoint."},"status":{"type":"string","enum":["waiting_for_host","queued","running","completed","failed","canceled"],"description":"waiting_for_host means the host computer is off; Hi, Moose waits up to 24 hours."},"mode":{"type":"string","enum":["cloud","host"],"description":"cloud when the run runs in the cloud, host when it was handed to the host computer."},"createdAt":{"type":["string","null"],"format":"date-time","description":"When the request was made."},"updatedAt":{"type":["string","null"],"format":"date-time","description":"When the status last changed."},"completedAt":{"type":["string","null"],"format":"date-time","description":"When the run finished, or null until then."},"runIds":{"type":"array","items":{"type":"string"},"description":"Run ids to pass to the runs and answers endpoints once completed."},"promptCount":{"type":"integer","description":"How many prompts the run covers."},"estimatedUnits":{"type":"integer","description":"The estimated allowance cost. 0 for host-only runs and bring-your-own-key plans."},"warning":{"type":["string","null"],"description":"A note about the request, for example that the host computer is off, or null."},"error":{"type":["object","null"],"properties":{"code":{"type":"string","description":"A stable code such as host_unavailable."},"message":{"type":"string","description":"What happened, in plain words."}},"description":"Why the request failed, or null."},"host":{"type":["object","null"],"properties":{"online":{"type":"boolean","description":"True when the host computer is checked in."},"lastSeenAt":{"type":["string","null"],"format":"date-time","description":"When the host computer last checked in, or null."}},"description":"The host computer handling the run, or null for cloud runs."},"replayed":{"type":"boolean","description":"Present and true when an Idempotency-Key matched an earlier request."}}},"WebhookCreate":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Public https endpoint. Private and local addresses are refused."},"events":{"type":"array","items":{"type":"string","enum":["run.completed","run.failed"]},"description":"Defaults to both."},"description":{"type":"string","maxLength":120,"description":"A note to tell webhooks apart in Settings. Optional."}}},"Webhook":{"type":"object","required":["id","url","events","description","active","createdAt","lastDeliveryAt","lastDeliveryStatus","consecutiveFailures"],"properties":{"id":{"type":"string","description":"The webhook id used in the webhook endpoints."},"url":{"type":"string","format":"uri","description":"The endpoint Hi, Moose posts events to."},"events":{"type":"array","items":{"type":"string"},"description":"The events this webhook receives."},"description":{"type":["string","null"],"description":"The note given when the webhook was registered, or null."},"active":{"type":"boolean","description":"Turned off automatically after 20 consecutive failed deliveries. Delete and register again to resume."},"createdAt":{"type":["string","null"],"format":"date-time","description":"When the webhook was registered."},"lastDeliveryAt":{"type":["string","null"],"format":"date-time","description":"When the last delivery was attempted, or null before the first."},"lastDeliveryStatus":{"type":["string","null"],"enum":["delivered","failed",null],"description":"How the last delivery ended, or null before the first."},"consecutiveFailures":{"type":"integer","description":"Failed deliveries in a row. At 20 the webhook is turned off."}}},"WebhookWithSecret":{"allOf":[{"$ref":"#/components/schemas/Webhook"},{"type":"object","required":["secret"],"properties":{"secret":{"type":"string","description":"Signing secret, starts with whsec_. Shown once."}}}]},"WebhookDelivery":{"type":"object","required":["id","event","status","runId","requestId","createdAt","deliveredAt","nextAttemptAt","attemptCount","attempts"],"properties":{"id":{"type":"string","description":"The delivery id, also sent as the X-HiMoose-Delivery header."},"event":{"type":"string","enum":["run.completed","run.failed","ping"],"description":"The event that was delivered."},"status":{"type":"string","enum":["pending","delivered","failed"],"description":"pending while retries remain, delivered on a 2xx answer, failed after the last attempt."},"runId":{"type":["string","null"],"description":"The run the event is about, or null for a ping."},"requestId":{"type":["string","null"],"description":"The API run request that started the run, or null."},"createdAt":{"type":["string","null"],"format":"date-time","description":"When the event was created."},"deliveredAt":{"type":["string","null"],"format":"date-time","description":"When the endpoint answered 2xx, or null."},"nextAttemptAt":{"type":["string","null"],"format":"date-time","description":"When the next retry is due, or null when none is planned."},"attemptCount":{"type":"integer","description":"How many attempts have been made so far."},"attempts":{"type":"array","items":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"When the attempt was made."},"httpStatus":{"type":["integer","null"],"description":"The status the endpoint answered, or null when it did not answer."},"error":{"type":["string","null"],"description":"Why the attempt failed, or null."},"durationMs":{"type":"integer","description":"How long the endpoint took to answer, in milliseconds."}}},"description":"Every attempt, oldest first."}}},"WebhookEventPayload":{"type":"object","description":"The JSON body Hi, Moose posts to your endpoint. Verify X-HiMoose-Signature before trusting it.","required":["id","event","createdAt","data"],"properties":{"id":{"type":"string","description":"Unique event id. Use it to ignore repeats."},"event":{"type":"string","enum":["run.completed","run.failed","ping"],"description":"The event name."},"createdAt":{"type":"string","format":"date-time","description":"When the event was created."},"data":{"type":"object","properties":{"projectId":{"type":"string","description":"The project the run belongs to."},"runId":{"type":["string","null"],"description":"The run id to pass as runId on the answers endpoint."},"requestId":{"type":["string","null"],"description":"The API run request that started this run, when there was one."},"status":{"type":"string","description":"completed, failed or canceled."},"trigger":{"type":"string","description":"scheduled or manual."},"startedAt":{"type":["string","null"],"format":"date-time","description":"When the run started."},"completedAt":{"type":["string","null"],"format":"date-time","description":"When the run finished."},"promptCount":{"type":"integer","description":"How many prompts the run covered."},"answerCount":{"type":"integer","description":"How many answers the run stored."},"error":{"type":["string","null"],"description":"Why the run failed, or null."},"links":{"type":"object","properties":{"run":{"type":"string","format":"uri","description":"The runs endpoint for the project."},"answers":{"type":"string","format":"uri","description":"The answers endpoint filtered to this run."},"stats":{"type":"string","format":"uri","description":"The daily stats endpoint for the project."}},"description":"Ready-made API addresses for the run's data."}},"description":"The event details."}}}}}}