Creates an HTTP endpoint that listens for incoming requests. Build REST APIs, receive webhooks, and accept file uploads.
Overview
The http-in node creates HTTP endpoints on your EdgeFlow server. Use it to:
- Receive webhooks - Accept callbacks from services like GitHub, Stripe, or Twilio
- Build REST APIs - Create CRUD endpoints for your IoT data
- Accept file uploads - Receive images, logs, or firmware files
- Create web interfaces - Serve dynamic pages with data from your flows
This node must be paired with an http-response node to send responses back to clients.
Every http-in node must have a corresponding http-response node in the flow. Without it, HTTP clients will timeout waiting for a response.
Properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | - | - | Display name for this node in the editor. |
method | string | GET | HTTP method to listen for: GET, POST, PUT, DELETE, PATCH, or ALL. | |
url | string | - | URL path for the endpoint (e.g., /api/sensors). Supports route parameters. | |
upload | boolean | - | false | Accept file uploads (multipart/form-data). |
swaggerDoc | string | - | - | OpenAPI/Swagger documentation for this endpoint. |
URL Patterns
The URL property supports Express.js route patterns:
| Pattern | Example URL | Description |
|---|---|---|
| /api/status | /api/status | Exact match |
| /api/sensors/:id | /api/sensors/temp01 | Named parameter (accessible via req.params.id) |
| /api/data/:year/:month | /api/data/2024/01 | Multiple parameters |
| /files/* | /files/images/photo.jpg | Wildcard match |
Full Endpoint URL
Your endpoints are available at:
http://<device-ip>:1880<your-url>
# Examples:
http://192.168.1.100:1880/api/sensors
http://localhost:1880/webhook/github Request Data
The http-in node provides access to all aspects of the incoming HTTP request:
| Property | Type | Description |
|---|---|---|
| msg.payload | object/string | Request body (parsed JSON or raw string) |
| msg.req.params | object | URL parameters (e.g., {id: "temp01"}) |
| msg.req.query | object | Query string (e.g., ?limit=10) |
| msg.req.headers | object | HTTP headers |
| msg.req.method | string | HTTP method (GET, POST, etc.) |
| msg.req.files | array | Uploaded files (when upload enabled) |
Outputs
The node outputs a message for each incoming HTTP request:
Output Message Format
{`{
"payload": { "temperature": 23.5, "humidity": 65 },
"req": {
"method": "POST",
"url": "/api/sensors/dht22",
"params": { "id": "dht22" },
"query": { "format": "json" },
"headers": {
"content-type": "application/json",
"x-api-key": "abc123"
},
"body": { "temperature": 23.5, "humidity": 65 }
},
"res": { /* response object - pass to http-response */ },
"_msgid": ""
}`} Examples
GitHub Webhook
Receive GitHub push events and log the commit information.
GitHub Webhook Handler
Receives push events from GitHub and extracts commit details.
View Flow JSON
[
{
"id": "http1",
"type": "http-in",
"name": "GitHub Webhook",
"method": "POST",
"url": "/webhook/github",
"wires": [["function1"]]
},
{
"id": "function1",
"type": "function",
"name": "Parse Event",
"func": "const event = msg.req.headers['x-github-event'];\nconst payload = msg.payload;\n\nif (event === 'push') {\n msg.payload = {\n repo: payload.repository.full_name,\n branch: payload.ref.split('/').pop(),\n commits: payload.commits.length,\n pusher: payload.pusher.name\n };\n}\nreturn msg;",
"wires": [["debug1", "response1"]]
},
{
"id": "response1",
"type": "http-response",
"name": "OK",
"statusCode": "200"
},
{
"id": "debug1",
"type": "debug",
"name": "Log"
}
] REST API for Sensors
Create a REST API to query sensor data from SQLite.
Sensor Data API
GET endpoint that returns sensor readings from the database.
View Flow JSON
[
{
"id": "http2",
"type": "http-in",
"name": "Get Readings",
"method": "GET",
"url": "/api/sensors/:id/readings",
"wires": [["function2"]]
},
{
"id": "function2",
"type": "function",
"name": "Build Query",
"func": "const sensorId = msg.req.params.id;\nconst limit = msg.req.query.limit || 100;\n\nmsg.topic = \`SELECT * FROM readings WHERE sensor_id = '\${sensorId}' ORDER BY timestamp DESC LIMIT \${limit}\`;\nreturn msg;",
"wires": [["sqlite1"]]
},
{
"id": "sqlite1",
"type": "sqlite",
"name": "Query DB",
"db": "sensors.db",
"wires": [["response2"]]
},
{
"id": "response2",
"type": "http-response",
"name": "JSON Response",
"statusCode": "200",
"headers": { "Content-Type": "application/json" }
}
] File Upload
Accept image uploads from IoT cameras.
Camera Image Upload
Receives image uploads and saves them to disk.
View Flow JSON
[
{
"id": "http3",
"type": "http-in",
"name": "Upload Image",
"method": "POST",
"url": "/api/camera/upload",
"upload": true,
"wires": [["function3"]]
},
{
"id": "function3",
"type": "function",
"name": "Process Upload",
"func": "if (msg.req.files && msg.req.files.length > 0) {\n const file = msg.req.files[0];\n msg.filename = '/data/images/' + Date.now() + '_' + file.originalname;\n msg.payload = file.buffer;\n return [msg, null];\n}\nmsg.payload = { error: 'No file uploaded' };\nmsg.statusCode = 400;\nreturn [null, msg];",
"outputs": 2,
"wires": [["write1"], ["response3"]]
},
{
"id": "write1",
"type": "file",
"name": "Save Image",
"filename": "",
"filenameType": "msg",
"wires": [["response3"]]
},
{
"id": "response3",
"type": "http-response",
"name": "Response"
}
] Security
Protect your HTTP endpoints with these best practices:
API Key Authentication
Validate API keys in headers before processing requests:
const apiKey = msg.req.headers['x-api-key'];
if (apiKey !== env.get('API_KEY')) {
msg.statusCode = 401;
msg.payload = { error: 'Unauthorized' };
return [null, msg]; // Send to error response
}
return [msg, null]; // Continue flow Rate Limiting
Use the delay node in rate-limit mode to prevent abuse. Limit requests to a reasonable rate (e.g., 10 requests per second per IP).
Input Validation
Always validate and sanitize user input. Never trust data from HTTP requests. Use a function node to check required fields and data types.
HTTPS
For production, use a reverse proxy (nginx, Caddy) with TLS certificates. EdgeFlow's built-in server supports HTTPS with custom certificates.
Troubleshooting
404 Not Found error
- Make sure the flow is deployed
- Check the URL path matches exactly (case-sensitive)
- Verify the HTTP method matches (GET vs POST)
- Ensure the URL starts with / (e.g., /api/data, not api/data)
Request times out / hangs
This usually means there's no http-response node, or the flow path doesn't reach it:
- Add an http-response node if missing
- Check for errors in function nodes that might stop the flow
- Ensure all code paths lead to http-response
- Add error handling to catch exceptions
POST body is empty or undefined
- Ensure the client sends
Content-Type: application/jsonheader - Verify the request body is valid JSON
- For form data, use
Content-Type: application/x-www-form-urlencoded - Check msg.req.body if msg.payload is empty
CORS errors in browser
Add CORS headers in the http-response node or use a function node:
msg.headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type"
};
return msg;