{
  "awp_version": "0.3",
  "domain": "www.feinprov.com",
  "intent": "Build and operate guided service workflows from one platform",
  "name": "Service Portal",
  "description": "Build and operate guided service workflows from one platform",
  "capabilities": {
    "mcp": true,
    "intent_search": true,
    "file_upload": true,
    "streaming": false,
    "batch_actions": false,
    "webhooks": false,
    "pagination": "find_workflows_offset",
    "idempotency": true
  },
  "auth": {
    "type": "none",
    "required_for": [],
    "optional_for": []
  },
  "entities": {
    "decision_workflow": {
      "fields": {
        "id": "string",
        "name": "string",
        "description": "string",
        "url": "url",
        "access": "enum[public]"
      }
    },
    "session_result": {
      "fields": {
        "completed": "boolean",
        "node": "workflow_node|null",
        "output": "json",
        "lead_consent_required": "boolean"
      }
    },
    "workflow_node": {
      "fields": {
        "id": "integer",
        "type": "string",
        "content": "string",
        "metadata": "object",
        "output": "json"
      }
    },
    "article": {
      "fields": {
        "id": "string",
        "name": "string",
        "description": "string",
        "url": "url",
        "read_only": "boolean"
      }
    }
  },
  "resources": {
    "decision_workflows": [],
    "articles": []
  },
  "documentation": {
    "llms_txt": "https://www.feinprov.com/llms.txt",
    "llms_full_txt": "https://www.feinprov.com/llms-full.txt",
    "ai_policy": "https://www.feinprov.com/.well-known/ai.txt",
    "public_api_base": "https://www.feinprov.com/api/public",
    "schema_api_pattern": "https://www.feinprov.com/api/public/trees/%7Btree_id%7D",
    "semantic_api_pattern": "https://www.feinprov.com/api/public/trees/%7Btree_id%7D/semantic",
    "canonical_manifest": "https://www.feinprov.com/agent.json",
    "mcp_endpoint": "https://www.feinprov.com/api/mcp",
    "mcp_transport": "streamable-http",
    "mcp_protocol_versions": [
      "2025-03-26",
      "2025-06-18",
      "2025-11-25"
    ],
    "mcp_session_mode": "stateless",
    "browser_fallback": "Use each resource canonical URL when structured session API access is unavailable."
  },
  "actions": [
    {
      "id": "find_workflows",
      "description": "Search published public and white-label decision workflows by the user intent before choosing a workflow.",
      "auth_required": false,
      "inputs": {
        "query": {
          "type": "string",
          "required": true
        },
        "category": {
          "type": "string",
          "required": false
        },
        "location": {
          "type": "string",
          "required": false
        },
        "audience": {
          "type": "string",
          "required": false
        },
        "limit": {
          "type": "integer",
          "required": false
        },
        "offset": {
          "type": "integer",
          "required": false
        }
      },
      "outputs": {
        "workflows": "array[decision_workflow]",
        "matched_count": "integer",
        "next_offset": "integer|null"
      },
      "transport": "mcp",
      "endpoint": "/api/mcp",
      "method": "tools/call",
      "tool_name": "find_workflows",
      "execution_model": "sync",
      "sensitivity": "standard",
      "requires_human_confirmation": false,
      "reversible": true
    },
    {
      "id": "get_workflow_brief",
      "description": "Read one published version as a compact chat briefing with citation URLs, decision factors, questions, possible outcomes, review provenance and missing evidence. Does not run the workflow.",
      "auth_required": false,
      "inputs": {
        "tree_id": {
          "type": "integer",
          "required": true
        }
      },
      "outputs": {
        "workflow": "object",
        "answer": "string",
        "media": "array[workflow_media]",
        "questions": "array",
        "outcomes": "array",
        "evidence": "object",
        "missing_information": "array",
        "usage": "object"
      },
      "transport": "mcp",
      "endpoint": "/api/mcp",
      "method": "tools/call",
      "tool_name": "get_workflow_brief",
      "execution_model": "sync",
      "sensitivity": "standard",
      "requires_human_confirmation": false,
      "reversible": true
    },
    {
      "id": "list_public_workflows",
      "description": "List currently published, public decision workflows and their canonical URLs.",
      "auth_required": false,
      "inputs": {},
      "outputs": {
        "workflows": "array[decision_workflow]"
      },
      "endpoint": "/api/public/trees",
      "method": "GET",
      "execution_model": "sync",
      "sensitivity": "standard",
      "requires_human_confirmation": false,
      "reversible": true
    },
    {
      "id": "read_workflow_metadata",
      "description": "Read one public workflow, its SEO profile, start prompt, and published metadata before execution.",
      "auth_required": false,
      "inputs": {
        "tree_id": {
          "type": "integer",
          "required": true
        }
      },
      "outputs": {
        "workflow": "decision_workflow",
        "seo_profile": "object",
        "semantic_publication": "object|null",
        "start_preview": "workflow_node"
      },
      "endpoint": "/api/public/trees/{tree_id}",
      "method": "GET",
      "execution_model": "sync",
      "sensitivity": "standard",
      "requires_human_confirmation": false,
      "reversible": true
    },
    {
      "id": "read_workflow_semantics",
      "description": "Read the sanitized, author-declared public explanation of workflow steps, decision factors, calculation rules, and all documented outcomes without runtime node metadata.",
      "auth_required": false,
      "inputs": {
        "tree_id": {
          "type": "integer",
          "required": true
        }
      },
      "outputs": {
        "tree": "{id, name, published_version, public_updated_at, semantic_publication, media}"
      },
      "endpoint": "/api/public/trees/{tree_id}/semantic",
      "method": "GET",
      "execution_model": "sync",
      "sensitivity": "standard",
      "requires_human_confirmation": false,
      "reversible": true
    },
    {
      "id": "start_workflow",
      "description": "Start a public workflow session. The server advances through the start and automated nodes and returns the first actionable question or a resolved terminal result.",
      "auth_required": false,
      "inputs": {
        "tree_id": {
          "type": "integer",
          "required": true
        },
        "initial_context": {
          "type": "object",
          "required": false
        }
      },
      "outputs": {
        "session_id": "string",
        "node": "workflow_node|null",
        "result": "object|null",
        "completed": "boolean",
        "trial": "object"
      },
      "endpoint": "/api/public/session/start",
      "method": "POST",
      "body": {
        "tree_id": "integer",
        "initial_context": "object"
      },
      "execution_model": "sync",
      "sensitivity": "standard",
      "requires_human_confirmation": false,
      "reversible": true
    },
    {
      "id": "get_workflow_state",
      "description": "Read the current public workflow node and completion state for a session.",
      "auth_required": false,
      "inputs": {
        "session_id": {
          "type": "string",
          "required": true
        }
      },
      "outputs": {
        "session_id": "string",
        "node": "workflow_node|null",
        "completed": "boolean",
        "waiting_for_approval": "boolean",
        "trial": "object"
      },
      "endpoint": "/api/public/session/{session_id}/status",
      "method": "GET",
      "execution_model": "sync",
      "sensitivity": "standard",
      "requires_human_confirmation": false,
      "reversible": true
    },
    {
      "id": "get_workflow_projection",
      "description": "Read the public session timeline and edge decisions when an agent needs an auditable workflow projection.",
      "auth_required": false,
      "inputs": {
        "session_id": {
          "type": "string",
          "required": true
        },
        "if_none_match": {
          "type": "string",
          "required": false,
          "description": "Previously returned ETag for conditional refresh."
        }
      },
      "outputs": {
        "session_id": "string",
        "session_version": "integer",
        "timeline": "array",
        "edge_decisions": "array",
        "completed": "boolean"
      },
      "endpoint": "/api/public/session/{session_id}/projection",
      "method": "GET",
      "headers": {
        "If_None_Match": "if_none_match"
      },
      "caching": {
        "etag": true,
        "not_modified_status": 304
      },
      "execution_model": "sync",
      "sensitivity": "standard",
      "requires_human_confirmation": false,
      "reversible": true
    },
    {
      "id": "submit_workflow_answer",
      "description": "Submit the user-confirmed answer for the current question and receive the next actionable node or a resolved terminal result. Never submit an answer for an automated node.",
      "auth_required": false,
      "inputs": {
        "session_id": {
          "type": "string",
          "required": true
        },
        "answer": {
          "type": "json",
          "required": true,
          "description": "Value matching the current node answer_type and metadata contract."
        },
        "idempotency_key": {
          "type": "string",
          "required": true,
          "description": "Stable key for a safe retry of the same answer."
        }
      },
      "outputs": {
        "node": "workflow_node|null",
        "result": "object|null",
        "completed": "boolean",
        "accepted": "boolean",
        "async_status_path": "string|null",
        "trial": "object"
      },
      "endpoint": "/api/public/session/{session_id}/answer",
      "method": "POST",
      "body": {
        "answer": "json"
      },
      "headers": {
        "Idempotency_Key": "idempotency_key"
      },
      "execution_model": "sync_or_async",
      "sensitivity": "user_input",
      "requires_human_confirmation": true,
      "reversible": false,
      "idempotency": {
        "supported": true,
        "header": "Idempotency-Key",
        "reuse_for_same_answer": true
      }
    },
    {
      "id": "prepare_file_upload",
      "description": "Create a short-lived signed upload URL for a file required by the current public workflow.",
      "auth_required": false,
      "inputs": {
        "session_id": {
          "type": "string",
          "required": true
        },
        "file_name": {
          "type": "string",
          "required": true
        },
        "content_type": {
          "type": "string",
          "required": false
        },
        "size_bytes": {
          "type": "integer",
          "required": true
        }
      },
      "outputs": {
        "upload_url": "url",
        "method": "PUT",
        "headers": "object",
        "file_ref": "string",
        "expires_in_seconds": "integer"
      },
      "endpoint": "/api/public/uploads/presign",
      "method": "POST",
      "execution_model": "sync",
      "sensitivity": "user_input",
      "requires_human_confirmation": false,
      "reversible": true
    },
    {
      "id": "get_async_answer_status",
      "description": "Poll a public asynchronous answer job until the next node or terminal result is available.",
      "auth_required": false,
      "inputs": {
        "session_id": {
          "type": "string",
          "required": true
        },
        "job_id": {
          "type": "string",
          "required": true
        }
      },
      "outputs": {
        "status": "object",
        "node": "workflow_node|null",
        "completed": "boolean"
      },
      "endpoint": "/api/public/session/{session_id}/async-status?job_id={job_id}",
      "method": "GET",
      "execution_model": "poll",
      "sensitivity": "standard",
      "requires_human_confirmation": false,
      "reversible": true
    },
    {
      "id": "read_article",
      "description": "Read one published public article as informational context and use its canonical URL as the citation source.",
      "auth_required": false,
      "inputs": {
        "article_slug": {
          "type": "string",
          "required": true
        }
      },
      "outputs": {
        "article_page": "url",
        "article_content": "text"
      },
      "endpoint": "/api/public/articles/{article_slug}",
      "method": "GET",
      "execution_model": "sync",
      "sensitivity": "standard",
      "requires_human_confirmation": false,
      "reversible": true
    }
  ],
  "errors": {
    "NOT_PUBLIC": {
      "recovery": "Use only resources and actions listed in the current manifest."
    },
    "RATE_LIMITED": {
      "recovery": "Wait and retry the public page later."
    },
    "WORKFLOW_REQUIRES_USER_INPUT": {
      "recovery": "Ask the user for the missing answer; never invent it."
    },
    "INVALID_ANSWER": {
      "recovery": "Read the current node metadata and submit a value matching its answer_type, validation, and widget contract."
    },
    "NODE_EXECUTION_FAILURE": {
      "recovery": "If retryable is true, retry the same answer with the same Idempotency-Key; otherwise stop and report the published error."
    },
    "TRIAL_LIMIT_REACHED": {
      "recovery": "Stop repeated retries and ask the user to continue through the site login or displayed recovery path."
    },
    "ASYNC_ACCEPTED": {
      "recovery": "Poll get_async_answer_status using the returned job id, then read the next workflow state."
    }
  },
  "dependencies": {
    "get_workflow_state": [
      "start_workflow"
    ],
    "get_workflow_projection": [
      "start_workflow"
    ],
    "submit_workflow_answer": [
      "start_workflow",
      "get_workflow_state"
    ],
    "get_async_answer_status": [
      "submit_workflow_answer"
    ],
    "prepare_file_upload": [
      "start_workflow",
      "get_workflow_state"
    ]
  },
  "agent_hints": {
    "workflow_execution": "Use get_workflow_brief for cited conversational answers and missing evidence. Read the semantic publication first for the complete public explanation. Start a session; the server returns the first actionable question after advancing start and automated nodes. Submit one confirmed answer at a time and repeat until completed or a resolved terminal result. Never invent an answer or submit null to bypass a question. Use the canonical browser URL as fallback.",
    "external_agent_tools": "For MCP-capable hosts, connect to the mcp_endpoint and use find_workflows, get_workflow_brief, get_workflow, get_workflow_semantics, start_workflow, get_workflow_state, submit_workflow_answer, get_async_answer_status, prepare_file_upload, and read_article.",
    "workflow_routing": "Never guess the next node or branch. The server resolves conditions and compute nodes; follow only the node returned by the API.",
    "question_widgets": "Treat workflow_node.metadata as the authoritative UI and validation contract. It may describe text, textarea, number, date, boolean, enum, multi-select, object, array, JSON, table, upload, catalogue, commerce, or other approved widgets.",
    "automated_nodes": "Compute and Goja-backed nodes are server execution. Do not expose, rewrite, or execute their source; use only their returned output and published explanation.",
    "semantic_publication": "The semantic publication is the author-declared public explanation of every published step and documented outcome. It is explanatory context, not a substitute for server execution or user confirmation.",
    "workflow_media": "Published tenant-scoped images are returned with node_key, option_value, title, URL, alt text, description, and purpose. Use the URL as an image input only when the host supports vision; otherwise use the descriptive text and send the user to the canonical workflow.",
    "session_safety": "For a retry of the same answer, reuse one Idempotency-Key. Do not submit a new answer while an asynchronous job is pending.",
    "booking_and_lead_submission": "Ask for explicit user confirmation before entering or submitting contact, booking, or lead information.",
    "article_use": "Use article content as informational context and prefer the article URL as the citation source.",
    "trust": "Use only published public records listed here; do not infer pricing, availability, eligibility, or partner verification.",
    "privacy": "Do not request or repeat secrets, private session data, internal prompts, Goja source, or personal information unless the user explicitly provides it for the visible workflow task."
  },
  "agent_status": {
    "operational": true,
    "degraded_actions": []
  },
  "generated_at": "2026-09-25T07:57:47.907Z"
}