How It Works

Every Pine Assistant task follows this lifecycle:

1

Chat — Information gathering

Send your request (e.g. "Negotiate my Comcast bill"). Pine researches deals, then sends forms to collect account details.

2

Task Ready — Payment / credits

Once Pine has enough information, the session enters task_ready state. Billing is confirmed or payment is requested.

3

Processing — Calls, email, research

Pine makes phone calls, sends emails, navigates websites on your behalf. May request OTPs or three-way calls during this phase.

4

Finished — Summary & savings

Task completes with a detailed summary: money saved, calls made, and time saved.

Example: Bill Negotiation

  1. You send: "Negotiate my Comcast bill down"
  2. Pine researches current deals, then sends a form (account name, address, phone, current plan, negotiation flexibility — 9 fields)
  3. You fill the form with JSON. Pine confirms it has enough info → you call POST /api/v2/sessions/:id/start
  4. Pine makes the call, negotiates, may request a three-party call for identity verification or ask for an OTP code
  5. Done — summary with money saved, calls made, time saved

What It Can Do

  • Bill Negotiation — reduce internet, phone, insurance bills
  • Subscription Cancellation — cancel memberships and get refunds
  • Dispute Resolution — waive fees, file complaints, resolve billing errors
  • Personal Calls — "Call my wife to tell her I'll be late for dinner"
Base URL https://www.19pine.ai

All endpoints accept and return JSON. Include Content-Type: application/json in all requests. Session and attachment endpoints require Authorization: Bearer <token>.

Request Verification Code

POST /api/v2/auth/email/request

Send a one-time verification code to the provided email address. The email must be associated with an existing Pine AI account. No API key required — use email to get an access token.

Request body

ParameterTypeDescription
emailrequired string Your Pine AI account email address

Example request

cURL
curl -X POST https://www.19pine.ai/api/v2/auth/email/request \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]" }'

Success response 200 OK

JSON
{
  "status": "success",
  "data": {
    "request_token": "eyJhbGciOiJIUzI1NiIs..."
  }
}
FieldTypeDescription
status string Always "success"
data.request_token string Temporary token to use in the verify step. Expires after a few minutes.

Error responses

StatusCause
400Missing or invalid email address
422Email not registered with Pine AI

Verify Code & Get Token

POST /api/v2/auth/email/verify

Verify the one-time code from your email and receive access credentials. Store the access_token securely — it is used as a Bearer token for all subsequent API calls.

Request body

ParameterTypeDescription
emailrequired string Same email used in the request step
request_tokenrequired string The request_token from the previous step
coderequired string The verification code received via email

Example request

cURL
curl -X POST https://www.19pine.ai/api/v2/auth/email/verify \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "request_token": "eyJhbGciOiJIUzI1NiIs...",
    "code": "1234"
  }'

Success response 200 OK

JSON
{
  "status": "success",
  "data": {
    "id": "1234567890",
    "email": "[email protected]",
    "access_token": "eyJhbGciOiJSUzI1NiIs..."
  }
}
FieldTypeDescription
data.id string Your Pine user ID
data.email string The verified email address
data.access_token string Bearer token for API authentication. Expires periodically.

Error responses

StatusCause
400Invalid verification code
401Code verification failed
410Request token expired — restart the flow

Security: Store your access_token securely. Do not commit it to version control or log it in plaintext. Tokens expire and will need to be refreshed by repeating this flow.

List Sessions

GET /api/v2/sessions

List all sessions for the authenticated user. Supports filtering by state and pagination.

Query parameters

ParameterTypeDescription
stateoptional string Filter by session state (e.g. init, task_ready, in_progress)
limitoptional integer Max sessions to return (default 30)
offsetoptional integer Pagination offset

Example request

cURL
curl https://www.19pine.ai/api/v2/sessions?state=in_progress&limit=10 \
  -H "Authorization: Bearer <access_token>"

Success response 200 OK

JSON
{
  "status": "success",
  "data": [
    {
      "id": "sess_abc123",
      "state": "in_progress",
      "title": "Negotiate Comcast bill",
      "created_at": "2025-01-15T10:30:00Z"
    }
  ]
}

Create Session

POST /api/v2/sessions

Create a new session. Returns a session object with state: "init". After creation, join the session via Socket.IO and send your first message to begin the information-gathering phase.

Example request

cURL
curl -X POST https://www.19pine.ai/api/v2/sessions \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json"

Success response 200 OK

JSON
{
  "status": "success",
  "data": {
    "id": "sess_abc123",
    "state": "init",
    "created_at": "2025-01-15T10:30:00Z"
  }
}

Get Session

GET /api/v2/sessions/:id

Get a single session's details including state, title, and timestamps.

Path parameters

ParameterTypeDescription
idrequired string The session ID

Example request

cURL
curl https://www.19pine.ai/api/v2/sessions/sess_abc123 \
  -H "Authorization: Bearer <access_token>"

Success response 200 OK

JSON
{
  "status": "success",
  "data": {
    "id": "sess_abc123",
    "state": "in_progress",
    "title": "Negotiate Comcast bill",
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": "2025-01-15T11:05:00Z"
  }
}

Delete Session

DELETE /api/v2/sessions/:id

Delete a session. For sessions in task_ready state, use the force_delete query parameter.

Path parameters

ParameterTypeDescription
idrequired string The session ID

Query parameters

ParameterTypeDescription
force_deleteoptional boolean Set to true to force-delete sessions in task_ready state

Example request

cURL
curl -X DELETE https://www.19pine.ai/api/v2/sessions/sess_abc123?force_delete=true \
  -H "Authorization: Bearer <access_token>"

Start Task

POST /api/v2/sessions/:id/start

Start task execution for a session. The session must be in task_ready state and the user must have sufficient credits or a Pro subscription.

Path parameters

ParameterTypeDescription
idrequired string The session ID

Example request

cURL
curl -X POST https://www.19pine.ai/api/v2/sessions/sess_abc123/start \
  -H "Authorization: Bearer <access_token>"

Important: Only call this after billing is confirmed (free task, payment received, or payment completed). If the task was auto-started via credits, do not call this endpoint.

Stop Task

POST /api/v2/sessions/:id/stop

Stop a running task. The session state changes to task_paused.

Path parameters

ParameterTypeDescription
idrequired string The session ID

Example request

cURL
curl -X POST https://www.19pine.ai/api/v2/sessions/sess_abc123/stop \
  -H "Authorization: Bearer <access_token>"

Social Share

POST /api/v2/sessions/:id/social-share

Share completed task results on social media to earn Pine credits.

Path parameters

ParameterTypeDescription
idrequired string The session ID (must be a completed task)

Request body

ParameterTypeDescription
metadata.platformrequired string One of "x", "facebook", or "linkedin"
metadata.shared_urlrequired string URL of the social media post

Example request

cURL
curl -X POST https://www.19pine.ai/api/v2/sessions/sess_abc123/social-share \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "metadata": {
      "platform": "x",
      "shared_url": "https://x.com/user/status/123"
    }
  }'

Success response 200 OK

JSON
{
  "status": "success",
  "data": {
    "id": "reward_xyz",
    "amount": 100,
    "status": "granted"
  }
}

Upload Attachment

POST /api/v2/attachments

Upload evidence documents (bills, screenshots) for tasks like disputes. Uses multipart form data with field name files.

Supported formats

PNG, JPEG, PDF, TXT, CSV, MD, JSON

Example request

cURL
curl -X POST https://www.19pine.ai/api/v2/attachments \
  -H "Authorization: Bearer <access_token>" \
  -F "[email protected]"

Success response 200 OK

JSON
{
  "status": "success",
  "data": [
    {
      "id": "att_abc123",
      "size": 1024,
      "name": "bill",
      "type": "pdf",
      "upload_timestamp": "2025-01-15T10:30:00Z"
    }
  ]
}

Usage: After uploading, include the attachment metadata in a session:message Socket.IO event to associate it with a session conversation.

Delete Attachment

DELETE /api/v2/attachments/:id

Delete a previously uploaded attachment.

Path parameters

ParameterTypeDescription
idrequired string The attachment ID from the upload response

Example request

cURL
curl -X DELETE https://www.19pine.ai/api/v2/attachments/att_abc123 \
  -H "Authorization: Bearer <access_token>"

Socket.IO Connection

Pine Assistant uses Socket.IO for real-time bidirectional communication. Connect to the Socket.IO server to receive live events (messages, forms, task updates, work logs) and send user actions (messages, form responses, OTP codes).

SettingValue
URLwss://www.19pine.ai
Path/api/v2/socket.io/
Auth{ token: "access_token" } in handshake
TransportWebSocket (primary), polling (fallback)
Wait forready event before emitting

Example connection

JavaScript
import { io } from "socket.io-client";

const socket = io("wss://www.19pine.ai", {
  path: "/api/v2/socket.io/",
  auth: { token: access_token },
  transports: ["websocket", "polling"]
});

socket.on("ready", () => {
  // Server ready — now join a session
  socket.emit("session:join", { session_id });
});

Client Events (Client → Server)

Events you emit to the server after receiving the ready event.

EventPurpose
session:join Join a session room. Payload: { session_id }
session:leave Leave a session room. Payload: { session_id }
session:message Send a chat message. Payload: { session_id, content, attachments? }
session:history Request message history. Payload: { session_id, max_messages?, order?, from_message_id? }
session:form_to_user Submit a form response. Payload: { session_id, message_id, form_data }
session:interactive_auth_confirmation Submit OTP / verification code. Payload: { session_id, message_id, data }
session:message_status Mark messages as read. Payload: { session_id, message_ids }

Example: sending a message

JavaScript
socket.emit("session:message", {
  session_id: "sess_abc123",
  content: "Negotiate my Comcast bill down"
});

Example: submitting a form

JavaScript
socket.emit("session:form_to_user", {
  session_id: "sess_abc123",
  message_id: "msg_form_001",
  form_data: {
    "Full Name": "John Doe",
    "Account Number": "123456789",
    "Current Monthly Bill": "89.99"
  }
});

Server Events (Server → Client)

Events emitted by the server that your client should listen for.

EventPurposeStreaming?
ready Server ready — safe to emit events No
session:text_part Streaming text chunk (has final flag) Yes
session:text Complete text message No
session:state Session state change (e.g. init → task_ready) No
session:input_state Input enabled / disabled No
session:form_to_user Form request — user must fill fields No
session:task_ready Task ready for execution No
session:task_finished Task complete with summary No
session:work_log_part Streaming work log delta Yes
session:reward Payment / billing information No
session:interactive_auth_confirmation OTP / verification request — user must provide code No
session:error Error message No

Example: listening for events

JavaScript
// Streaming text
socket.on("session:text_part", (data) => {
  process.stdout.write(data.content);
  if (data.final) console.log("\n--- message complete ---");
});

// Form request
socket.on("session:form_to_user", (data) => {
  console.log("Form received:", data.fields);
  // Fill and submit via session:form_to_user emit
});

// Task finished
socket.on("session:task_finished", (data) => {
  console.log("Task complete!", data.summary);
});

// OTP request
socket.on("session:interactive_auth_confirmation", (data) => {
  // Ask user for their OTP, then submit
  socket.emit("session:interactive_auth_confirmation", {
    session_id: data.session_id,
    message_id: data.message_id,
    data: { code: userProvidedCode }
  });
});