Install
openclaw skills install mindstudio-http-request-block-skillConfigure and use the MindStudio HTTP Request block to send data to external APIs, webhooks, and web services. Use this skill whenever a user mentions HTTP r...
openclaw skills install mindstudio-http-request-block-skillA production reference for configuring the HTTP Request block correctly, reliably, and safely across any MindStudio workflow.
Before writing any configuration, determine what the user is trying to do. Match their intent to one of the five scenarios below, then ask only the questions listed for that scenario. Do not ask questions from other scenarios. Do not guess at variable names — use exactly what the user provides.
If the user's intent is already clear from context (e.g. they said "POST my AI output to a Make webhook"), skip straight to the questions for that scenario without asking them to confirm the scenario type.
Trigger: User wants to retrieve data from an API — weather, stock prices, user records, CRM contacts, etc.
Ask the user:
Authorization, X-Api-Key)?symbol=AAPL, user_id={{userId}})Method: GET
Body: None
Content-Type: none
Trigger: User wants to submit data to an external system — form submissions, JSON payloads, lead captures, AI output delivery, etc.
Ask the user:
{{customer_name}}, {{ai_output}}, {{email}}).Method: POST
Content-Type: application/json (default unless user specifies otherwise)
Trigger: User wants to update an existing record in an external system — CRM contact, database row, project record, etc.
Ask the user:
https://api.example.com/contacts){{contact_id}}, {{record_id}}) — this gets appended to the URLMethod: PATCH (partial update) or PUT (full replacement)
Content-Type: application/json
Trigger: User wants to remove a record or resource from an external system.
Ask the user:
Method: DELETE
Body: None
Content-Type: none
Safety rule: Never generate a DELETE configuration without explicit confirmation from the user that removal is the intended action.
Trigger: User wants to fire a signal to an external system when something happens in the workflow — webhooks, Make/Zapier triggers, notifications, pipeline kicks, inter-workflow calls, etc.
Ask the user:
{"accepted": true}, some return 200 with no body)Method: POST
Content-Type: application/json
Once the user answers the questions for their scenario, output a complete, ready-to-paste block configuration using this structure:
URL : [full URL, with variables where needed]
Method : [GET / POST / PATCH / PUT / DELETE]
Content-Type : [application/json / none / other]
Headers:
[Key] : [Value]
[Key] : [Value]
Parameters (GET only):
[key] : [value]
Body:
[JSON or form structure using exact variable names]
Output Variable: [descriptiveName]
Then immediately follow with the downstream handling block:
On success (ok = true):
- [what to do with the response]
- [how to access specific fields]
On failure (ok = false):
- Check {{outputVar.status}} for error code
- [recommended branch or fallback]
Every HTTP Request block returns four fields regardless of method or endpoint:
| Field | Type | Description |
|---|---|---|
ok | Boolean | true if response status is in the 2xx range |
status | Number | Numeric HTTP status code (e.g. 200, 404, 500) |
statusText | String | Status description (e.g. "OK", "Not Found") |
response | String | Full response body as a raw string |
Access them downstream using:
{{outputVar.ok}}
{{outputVar.status}}
{{outputVar.statusText}}
{{outputVar.response}}
If the response body is JSON, pass {{outputVar.response}} to a downstream Generate Text or Run Function block to parse and extract fields. Never access nested fields directly from the raw response string.
https://https://api.example.com/users/{{userId}}| Method | Use Case |
|---|---|
GET | Retrieve data — no body |
POST | Create a resource or trigger an action |
PATCH | Partially update an existing resource |
PUT | Fully replace an existing resource |
DELETE | Remove a resource — no body |
HEAD | Retrieve headers only |
OPTIONS | Discover available methods |
Content-Type : application/json
Authorization : Bearer {{apiKey}}
Accept : application/json
X-Api-Key : {{serviceKey}}
Content-Type when sending a bodyAuthorization when the endpoint requires it{{variable}} syntaxQuery string key-value pairs. Used with GET requests.
symbol : {{ticker}}
token : {{apiKey}}
from : {{startDate}}
| Option | When to Use |
|---|---|
application/json | Structured JSON data (most common) |
application/x-www-form-urlencoded | HTML form submissions |
multipart/form-data | File uploads or mixed form data |
text/plain | Raw text payloads |
application/XML | XML-based APIs |
custom | Any content type not in this list |
none | GET, HEAD, DELETE — no body |
For application/json:
{
"customer_name": "{{customer_name}}",
"email": "{{email}}",
"ai_output": "{{generatedText}}",
"submitted_at": "{{timestamp}}"
}
For application/x-www-form-urlencoded:
customer_name={{customer_name}}&email={{email}}
For GET / DELETE: Leave body empty. Set Content-Type to none.
Always set this. Use a descriptive name that reflects the source.
makeResponse
crmResult
stockData
userRecord
patchResult
Content-Type when sending a body; always include auth headers when required; never omit required headers{{variableName}} syntax everywhere; use dot notation for nested data from upstream blocksok before using response downstream{{outputVar.ok}} is true before proceeding{{outputVar.response}}| Status | Meaning | Fix |
|---|---|---|
400 | Bad Request | Body is malformed or missing required fields |
401 | Unauthorized | Missing or invalid API key / token |
403 | Forbidden | Valid key but insufficient permissions |
404 | Not Found | URL is wrong or resource does not exist |
422 | Unprocessable Entity | JSON is valid but field values are invalid |
429 | Rate Limited | Too many requests — add a Wait block |
500 | Server Error | External API issue — retry or alert |
503 | Service Unavailable | External API is down — retry later |
{{outputVar.response}} for debuggingMissing required data:
API failure:
{{outputVar.ok}} immediately after the blockRetry logic:
Response validation:
{{outputVar.response}} is non-empty after a 2xxAbsolute. No exceptions.
URL : https://finnhub.io/api/v1/quote?symbol={{ticker}}&token={{finnhubApiKey}}
Method : GET
Content-Type : none
Headers :
Accept : application/json
Body : (empty)
Output Variable: stockData
On success: parse {{stockData.response}} — field "c" is current price
On failure: log {{stockData.status}} — check API key and ticker symbol
URL : https://hook.us1.make.com/{{webhookId}}
Method : POST
Content-Type : application/json
Headers :
Content-Type : application/json
Body:
{
"customer_name": "{{customer_name}}",
"email": "{{email}}",
"ai_output": "{{generatedText}}",
"submitted_at": "{{timestamp}}"
}
Output Variable: makeResponse
On success: Make returns {"accepted": true} — log and continue
On failure: log {{makeResponse.status}} — verify webhook URL is active
URL : https://api.hubspot.com/crm/v3/objects/contacts/{{contact_id}}
Method : PATCH
Content-Type : application/json
Headers :
Content-Type : application/json
Authorization : Bearer {{hubspotApiKey}}
Body:
{
"properties": {
"lead_score": "{{lead_score}}",
"last_contacted": "{{timestamp}}",
"notes": "{{ai_summary}}"
}
}
Output Variable: crmResult
On success: {{crmResult.ok}} = true — record updated
On 404: contact_id is wrong — check the variable source block
On 422: field name mismatch — verify HubSpot property names
URL : https://api.example.com/records/{{record_id}}
Method : DELETE
Content-Type : none
Headers :
Authorization : Bearer {{apiKey}}
Body : (empty)
Output Variable: deleteResult
On success: status 204 — no body returned, deletion confirmed
On 404: record_id does not exist or was already deleted
On 403: API key does not have delete permissions
URL : https://hooks.zapier.com/hooks/catch/{{zapId}}/{{hookId}}/
Method : POST
Content-Type : application/json
Headers :
Content-Type : application/json
Body:
{
"event": "workflow_completed",
"user_email": "{{email}}",
"result": "{{ai_output}}",
"timestamp": "{{timestamp}}"
}
Output Variable: zapierResponse
On success: Zapier returns {"status": "success"} — trigger confirmed
On failure: log {{zapierResponse.status}} — verify Zap is active and URL is correct
URL and method:
https://{{variableName}} syntaxHeaders:
Content-Type is set and matches the body formatBody:
Content-Type headerOutput:
{{outputVar.ok}} before using {{outputVar.response}}ok = false