Documentation / Recursos Avançados
Recursos Avançados

How to Control the Appointment Access List via External API

Overview

eAgenda allows you to automatically validate whether a client is authorized to make an appointment using an Access List connected to an external API.

When the client provides their ID number during the booking process, eAgenda sends an HTTP POST request to the configured URL, using a timestamp and HMAC-SHA256 signature to ensure security and communication integrity.

In this document you will find:

  • How the request structure sent by eAgenda works
  • How to develop the external API responsible for validation
  • How to create the Access List that validates via external API
  • How to share the list link with your clients

Request Structure Sent by eAgenda

Request Body (JSON)

eAgenda sends the identifier provided by the client in the configured field (e.g., ID number):

{ “identifier”: “12345678901” }

{
  "identifier": "12345678901"
}

Headers Sent

The headers add security and authentication:

  • X-Timestamp: UNIX timestamp of the request
  • X-Signature: HMAC-SHA256 hash generated from the body + timestamp
  • Content-Type: application/json

Method

POST

How to Develop Your External API

The external API must:

  1. Verify the timestamp to prevent replay attacks
  2. Validate the HMAC-SHA256 signature
  3. Check whether the provided identifier is authorized
  4. Respond with { "authorized": true/false }

Complete Example in Python + Flask

from flask import Flask, request, jsonify import hmac import hashlib import time

app = Flask(__name__)

SECRET_KEY = “my-super-secure-secret-key-123”

AUTHORIZED_CLIENTS = [ “01234567890”, “12345678901”, “98765432100”, “11122233344” ]

TIME_TOLERANCE = 120

def verify_signature(body, timestamp, received_signature): message = body + timestamp expected_signature = hmac.new( SECRET_KEY.encode(‘utf-8’), message.encode(‘utf-8’), hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected_signature, received_signature)

@app.route(‘/validate’, methods=[‘POST’]) def validate_client(): timestamp_header = request.headers.get(‘X-Timestamp’) signature_header = request.headers.get(‘X-Signature’)

if not timestamp\_header or not signature\_header:
    return jsonify({"error": "X-Timestamp and X-Signature headers are required"}), 400

body = request.get\_data(as\_text=True)

try:
    request\_time = int(timestamp\_header)
    current\_time = int(time.time())
    diff = abs(current\_time - request\_time)
    if diff > TIME\_TOLERANCE:
        return jsonify({"authorized": False, "error": "Request expired"}), 403
except:
    return jsonify({"error": "Invalid timestamp"}), 400

if not verify\_signature(body, timestamp\_header, signature\_header):
    return jsonify({"authorized": False, "error": "Invalid signature"}), 403

data = request.get\_json()
identifier = data.get("identifier")

if not identifier:
    return jsonify({"error": "Field 'identifier' is required"}), 400

authorized = identifier in AUTHORIZED\_CLIENTS

return jsonify({"authorized": authorized, "identifier": identifier}), 200

@app.route(‘/health’, methods=[‘GET’]) def health(): return jsonify({ “status”: “online”, “secret_key_configured”: True, “authorized_clients_count”: len(AUTHORIZED_CLIENTS) }), 200

if __name__ == “__main__”: app.run(debug=True, port=5000)

from flask import Flask, request, jsonify
import hmac
import hashlib
import time

app = Flask(__name__)

SECRET_KEY = "my-super-secure-secret-key-123"

AUTHORIZED_CLIENTS = [
    "01234567890",
    "12345678901",
    "98765432100",
    "11122233344"
]

TIME_TOLERANCE = 120

def verify_signature(body, timestamp, received_signature):
    message = body + timestamp
    expected_signature = hmac.new(
        SECRET_KEY.encode('utf-8'),
        message.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected_signature, received_signature)

@app.route('/validate', methods=['POST'])
def validate_client():
    timestamp_header = request.headers.get('X-Timestamp')
    signature_header = request.headers.get('X-Signature')

    if not timestamp_header or not signature_header:
        return jsonify({"error": "X-Timestamp and X-Signature headers are required"}), 400

    body = request.get_data(as_text=True)

    try:
        request_time = int(timestamp_header)
        current_time = int(time.time())
        diff = abs(current_time - request_time)
        if diff > TIME_TOLERANCE:
            return jsonify({"authorized": False, "error": "Request expired"}), 403
    except:
        return jsonify({"error": "Invalid timestamp"}), 400

    if not verify_signature(body, timestamp_header, signature_header):
        return jsonify({"authorized": False, "error": "Invalid signature"}), 403

    data = request.get_json()
    identifier = data.get("identifier")

    if not identifier:
        return jsonify({"error": "Field 'identifier' is required"}), 400

    authorized = identifier in AUTHORIZED_CLIENTS

    return jsonify({"authorized": authorized, "identifier": identifier}), 200

@app.route('/health', methods=['GET'])
def health():
    return jsonify({
        "status": "online",
        "secret_key_configured": True,
        "authorized_clients_count": len(AUTHORIZED_CLIENTS)
    }), 200

if __name__ == "__main__":
    app.run(debug=True, port=5000)

Response Examples

Authorized client

{ “authorized”: true, “identifier”: “12345678901” }

{
  "authorized": true,
  "identifier": "12345678901"
}

Unauthorized client

{ “authorized”: false, “identifier”: “12345678901” }

{
  "authorized": false,
  "identifier": "12345678901"
}

How to Create the Access List That Validates via External API

Step 1 — Access the platform

  1. Go to: [https://eagenda.com.br](https://eagenda.com.br)
  2. Log in with your account.

Step 2 — Navigate to the correct menu

  1. In the sidebar menu, click on Account
  2. Click on Client Access

Step 3 — Create a new list

  1. Click on New List

  1. In the List Name field, enter any name (e.g., test)
  2. The remaining fields can be left blank

Step 4 — Configure the validation type

  • Required login: uncheck
  • Use External Access List: check
  • Access Key Type: select CPF

Step 5 — Configure the external integration

Fill in:

  • External API URL: E.g.: https://yourserver.com/validate
  • Secret Key: E.g.: my-super-secure-secret-key-123

Step 6 — Finish

Click Save.

Your list is now ready to automatically validate each ID number through the external API.


How to Share the List with Clients

  1. In eAgenda, go to Account → Client Access
  2. Locate the created list
  3. Click on Actions
  4. Select Copy shared link

This link can be sent to clients: They enter their ID number → the system queries the API → automatically grants or blocks the appointment.

Contact Us or Learn More

We are here to help! Access our official channels:

📞 WhatsApp : Click here to send us a message 🌐 eAgenda Platform : Discover eAgenda 🏢 Our Company : Mupi Systems – Innovative Solutions 📧 Email : contato@mupisystems.com.br 📚 Tutorials and Documentation : Access our guides and tutorials