Once a user (or agent) purchases a Payment Plan, the user can query all the AI Agents associated to that plan. For identifying the user as a valid subscriber, they need to send HTTP requests to the AI Agent via a Nevermined Proxy instance and include a valid Access Token. This is sent using the standard HTTP Authorization header.
Nevermined Proxy instances are standard HTTP Proxies in charge of authorizing users trying to access AI Agents or Services.
Once a user is a subscriber, sending a request is quite simple.

Get the AI Agent or Service Access Token

const credentials = await payments.agents.getAgentAccessToken(planId, agentId)
// OUTPUT: credentials:
// {
//   accessToken: 'eJyNj0sKgDAURP9lJQ ....',
//   proxies: [ 'https://proxy.nevermined.app' ]
// }  

Sending a query to the AI Agent

If the response of the getAgentAccessToken method contains a valid accessToken, the user can query the AI Agent making a standard HTTP request. This request must be sent directly to the Agent (the description of the Agent API is in the Agent Metadata) or if the agentAccessParams includes an entry in the proxies array, through one of the Nevermined Proxy instances listed in the proxies array of the response.
Because Nevermined authorizes standard HTTP requests, they can be used to protect any kind of AI Agent or Service exposing an HTTP API.

Using cURL

export AGENT_ACCESS_TOKEN="eJyNj0sKgDAURP9lJQ..."

curl -k -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_ACCESS_TOKEN" \
  -d '{"query": "hey there"}' \
  https://my.agent.io/prompt

Using Programming Languages

const agentHTTPOptions = {
  method: 'POST',
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
    Authorization: `Bearer ${credentials.accessToken}`,
  },
  body: JSON.stringify({
    query: "What's the weather like today?",
    parameters: {
      location: "New York"
    }
  })
}

const response = await fetch(new URL('https://my.agent.io/prompt'), agentHTTPOptions)
const result = await response.json()
console.log('Agent response:', result)

Complete Query Flow Example

Here’s a complete example showing the full flow from getting access tokens to querying an agent:
async function queryAIAgent(planId: string, agentId: string, query: string) {
  try {
    // Step 1: Get access credentials
    const credentials = await payments.agents.getAgentAccessToken(planId, agentId)
    
    if (!credentials.accessToken) {
      throw new Error('No access token received - check if plan is valid and has balance')
    }
    
    // Step 2: Get agent details
    const agent = await payments.agents.getAgent(agentId)
    const endpoint = agent.endpoints[0] // Use first endpoint
    
    // Step 3: Make the request
    const response = await fetch(endpoint.url, {
      method: endpoint.method || 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${credentials.accessToken}`
      },
      body: JSON.stringify({ query })
    })
    
    if (response.status === 402) {
      throw new Error('Payment required - insufficient credits or plan expired')
    }
    
    if (!response.ok) {
      throw new Error(`Agent request failed: ${response.status} ${response.statusText}`)
    }
    
    const result = await response.json()
    
    // Step 4: Check remaining balance (optional)
    const balance = await payments.plans.getPlanBalance(planId)
    console.log(`Remaining credits: ${balance.balance}`)
    
    return result
    
  } catch (error) {
    console.error('Query failed:', error.message)
    throw error
  }
}

// Usage
const result = await queryAIAgent(planId, agentId, "Explain quantum computing")
console.log('AI Response:', result)

Handling Different Response Types

AI agents can return various types of responses. Here’s how to handle them:
async function handleAgentResponse(response: Response) {
  const contentType = response.headers.get('content-type')
  
  if (contentType?.includes('application/json')) {
    // JSON response (most common)
    return await response.json()
  } else if (contentType?.includes('text/')) {
    // Text response
    return await response.text()
  } else if (contentType?.includes('image/')) {
    // Image response
    const blob = await response.blob()
    return URL.createObjectURL(blob)
  } else {
    // Binary or other response
    return await response.arrayBuffer()
  }
}

Error Handling and Status Codes

Best Practices

Token Management

  • Cache access tokens (they’re valid for a limited time)
  • Refresh tokens when they expire
  • Never expose tokens in client-side logs

Error Handling

  • Always check response status codes
  • Implement retry logic for network failures
  • Handle 402 responses by prompting for plan renewal

Performance

  • Reuse access tokens across multiple requests
  • Implement request timeouts
  • Use appropriate HTTP methods (GET, POST)

Monitoring

  • Track credit usage patterns
  • Monitor response times and error rates
  • Set up alerts for low credit balances

Advanced Usage Patterns

Batch Requests

For efficiency, you can send multiple queries in a single request:
const batchQuery = {
  requests: [
    { id: '1', query: 'What is AI?' },
    { id: '2', query: 'Explain machine learning' },
    { id: '3', query: 'Define neural networks' }
  ]
}

const response = await fetch(agentEndpoint, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`
  },
  body: JSON.stringify(batchQuery)
})

Streaming Responses

For long-running AI operations, you might want to handle streaming responses:
const response = await fetch(agentEndpoint, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${accessToken}`,
    'Accept': 'text/event-stream'
  },
  body: JSON.stringify({ query, stream: true })
})

const reader = response.body?.getReader()
if (reader) {
  while (true) {
    const { done, value } = await reader.read()
    if (done) break
    
    const chunk = new TextDecoder().decode(value)
    console.log('Streaming chunk:', chunk)
  }
}

Next Steps

Now that you know how to query AI agents, learn how to: