Skip to main content

http-in

Create HTTP endpoints to receive webhooks and API requests.

http-in
input v1.0.0

Creates an HTTP endpoint that listens for incoming requests. Build REST APIs, receive webhooks, and accept file uploads.

http api rest webhook endpoint
Inputs
0
Outputs
1

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.

Important

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
[
  &#123;
    "id": "http1",
    "type": "http-in",
    "name": "GitHub Webhook",
    "method": "POST",
    "url": "/webhook/github",
    "wires": [["function1"]]
  &#125;,
  &#123;
    "id": "function1",
    "type": "function",
    "name": "Parse Event",
    "func": "const event = msg.req.headers['x-github-event'];\nconst payload = msg.payload;\n\nif (event === 'push') &#123;\n  msg.payload = &#123;\n    repo: payload.repository.full_name,\n    branch: payload.ref.split('/').pop(),\n    commits: payload.commits.length,\n    pusher: payload.pusher.name\n  &#125;;\n&#125;\nreturn msg;",
    "wires": [["debug1", "response1"]]
  &#125;,
  &#123;
    "id": "response1",
    "type": "http-response",
    "name": "OK",
    "statusCode": "200"
  &#125;,
  &#123;
    "id": "debug1",
    "type": "debug",
    "name": "Log"
  &#125;
]

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
[
  &#123;
    "id": "http2",
    "type": "http-in",
    "name": "Get Readings",
    "method": "GET",
    "url": "/api/sensors/:id/readings",
    "wires": [["function2"]]
  &#125;,
  &#123;
    "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 = '\$&#123;sensorId&#125;' ORDER BY timestamp DESC LIMIT \$&#123;limit&#125;\`;\nreturn msg;",
    "wires": [["sqlite1"]]
  &#125;,
  &#123;
    "id": "sqlite1",
    "type": "sqlite",
    "name": "Query DB",
    "db": "sensors.db",
    "wires": [["response2"]]
  &#125;,
  &#123;
    "id": "response2",
    "type": "http-response",
    "name": "JSON Response",
    "statusCode": "200",
    "headers": &#123; "Content-Type": "application/json" &#125;
  &#125;
]

File Upload

Accept image uploads from IoT cameras.

Camera Image Upload

Receives image uploads and saves them to disk.

View Flow JSON
[
  &#123;
    "id": "http3",
    "type": "http-in",
    "name": "Upload Image",
    "method": "POST",
    "url": "/api/camera/upload",
    "upload": true,
    "wires": [["function3"]]
  &#125;,
  &#123;
    "id": "function3",
    "type": "function",
    "name": "Process Upload",
    "func": "if (msg.req.files && msg.req.files.length > 0) &#123;\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&#125;\nmsg.payload = &#123; error: 'No file uploaded' &#125;;\nmsg.statusCode = 400;\nreturn [null, msg];",
    "outputs": 2,
    "wires": [["write1"], ["response3"]]
  &#125;,
  &#123;
    "id": "write1",
    "type": "file",
    "name": "Save Image",
    "filename": "",
    "filenameType": "msg",
    "wires": [["response3"]]
  &#125;,
  &#123;
    "id": "response3",
    "type": "http-response",
    "name": "Response"
  &#125;
]

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/json header
  • 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;