Skip to main content
Make HTTP requests via the mobile device, useful for API calls that need to appear from a mobile IP address or with mobile-specific headers.

Method

page.request()

Performs an HTTP request through the device’s network connection.
page.request(url: string, options?: RequestOptions): Result
Parameters:
  • url: URL to make the request to
  • options (optional): Request options
Options:
interface RequestOptions {
  method?: string                      // HTTP method (default: 'GET')
  headers?: Record<string, string>     // Request headers
  body?: string | ReadableStream       // Request body
  timeout?: number                     // Request timeout in milliseconds
}
Returns: Result object with:
  • value(options?): Promise that resolves to response data
  • stream: ReadableStream of response body (for streaming)
Examples:
// Simple GET request
const result = await page.request('https://api.example.com/data')
const data = await result.value({ close: true })
console.log('Response:', data)

// POST request with JSON
const result = await page.request('https://api.example.com/submit', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token123'
  },
  body: JSON.stringify({ key: 'value' })
})
const response = await result.value({ close: true })

// With timeout
const result = await page.request('https://slow-api.example.com/data', {
  timeout: 30000  // 30 seconds
})

Complete examples

API calls with mobile headers

// Make API call that appears to come from mobile device
const result = await page.request('https://api.example.com/mobile-only', {
  method: 'GET',
  headers: {
    'User-Agent': 'MyApp/1.0 (iOS 17.2; iPhone)',
    'X-Device-Type': 'mobile',
    'Authorization': 'Bearer ' + authToken
  }
})

const data = await result.value({ close: true })
console.log('Mobile API response:', data)

POST data to API

async function submitForm(formData) {
  const result = await page.request('https://api.example.com/forms', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(formData)
  })

  const response = await result.value({ close: true })

  if (response.status === 200) {
    console.log('Form submitted successfully')
    return response.data
  } else {
    throw new Error(`Form submission failed: ${response.status}`)
  }
}

await submitForm({
  name: 'John Doe',
  email: 'john@example.com',
  message: 'Hello!'
})

Authenticated API requests

async function makeAuthenticatedRequest(endpoint, accessToken) {
  const result = await page.request(`https://api.example.com${endpoint}`, {
    method: 'GET',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Accept': 'application/json'
    }
  })

  const response = await result.value({ close: true })
  return JSON.parse(response)
}

// Usage
const userData = await makeAuthenticatedRequest('/user/profile', token)
console.log('User profile:', userData)

const orders = await makeAuthenticatedRequest('/user/orders', token)
console.log('Orders:', orders)

Download file

async function downloadFile(url) {
  const result = await page.request(url, {
    method: 'GET'
  })

  const responseData = await result.value({ close: true })

  // Save or process the file data
  console.log('Downloaded file, size:', responseData.length)
  return responseData
}

const fileData = await downloadFile('https://example.com/file.pdf')

Streaming response

async function streamLargeResponse(url) {
  const result = page.request(url)

  // Get the readable stream
  const stream = result.stream

  // Process chunks as they arrive
  const reader = stream.getReader()

  while (true) {
    const { done, value } = await reader.read()

    if (done) {
      console.log('Stream complete')
      break
    }

    // Process chunk
    console.log('Received chunk, size:', value.length)
  }

  // Get final response metadata
  const response = await result.value()
  console.log('Response status:', response.status)
}

await streamLargeResponse('https://api.example.com/large-data')

Upload file

async function uploadFile(fileData, filename) {
  // Create a readable stream from file data
  const stream = new ReadableStream({
    start(controller) {
      controller.enqueue(fileData)
      controller.close()
    }
  })

  const result = await page.request('https://api.example.com/upload', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/octet-stream',
      'X-Filename': filename
    },
    body: stream
  })

  const response = await result.value({ close: true })
  return response
}

const fileData = new Uint8Array([/* file bytes */])
await uploadFile(fileData, 'document.pdf')

GraphQL query

async function graphqlQuery(query, variables = {}) {
  const result = await page.request('https://api.example.com/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      query,
      variables
    })
  })

  const response = await result.value({ close: true })
  const data = JSON.parse(response)

  if (data.errors) {
    throw new Error('GraphQL errors: ' + JSON.stringify(data.errors))
  }

  return data.data
}

// Usage
const data = await graphqlQuery(`
  query GetUser($id: ID!) {
    user(id: $id) {
      name
      email
    }
  }
`, { id: '123' })

console.log('User data:', data.user)

Retry failed requests

async function requestWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      console.log(`Request attempt ${attempt}/${maxRetries}`)

      const result = await page.request(url, {
        ...options,
        timeout: 10000
      })

      const response = await result.value({ close: true })
      return response

    } catch (error) {
      console.error(`Attempt ${attempt} failed:`, error.message)

      if (attempt === maxRetries) {
        throw new Error(`Request failed after ${maxRetries} attempts`)
      }

      // Wait before retrying (exponential backoff)
      await new Promise(resolve => setTimeout(resolve, 1000 * attempt))
    }
  }
}

const data = await requestWithRetry('https://api.example.com/data', {
  method: 'GET'
})

Paginated API requests

async function fetchAllPages(baseUrl) {
  const allData = []
  let page = 1
  let hasMore = true

  while (hasMore) {
    const result = await page.request(`${baseUrl}?page=${page}&limit=100`, {
      method: 'GET',
      headers: {
        'Accept': 'application/json'
      }
    })

    const response = await result.value({ close: true })
    const data = JSON.parse(response)

    allData.push(...data.items)

    hasMore = data.hasMore
    page++

    console.log(`Fetched page ${page - 1}, total items: ${allData.length}`)
  }

  return allData
}

const allItems = await fetchAllPages('https://api.example.com/items')
console.log(`Fetched ${allItems.length} total items`)

Check API availability

async function checkAPIHealth() {
  try {
    const result = await page.request('https://api.example.com/health', {
      method: 'GET',
      timeout: 5000
    })

    const response = await result.value({ close: true })

    if (response.status === 200) {
      console.log('API is healthy')
      return true
    } else {
      console.warn('API returned status:', response.status)
      return false
    }
  } catch (error) {
    console.error('API is down:', error.message)
    return false
  }
}

const isHealthy = await checkAPIHealth()

Best practices

Always set timeouts for requests to avoid hanging:
const result = await page.request(url, {
  timeout: 30000  // 30 seconds
})
Call value({ close: true }) to properly close the response:
const data = await result.value({ close: true })
Wrap requests in try-catch blocks:
try {
  const result = await page.request(url)
  const data = await result.value({ close: true })
} catch (error) {
  console.error('Request failed:', error)
}
Include appropriate headers for mobile API endpoints:
const result = await page.request(url, {
  headers: {
    'User-Agent': 'MyApp/1.0',
    'X-Platform': 'mobile'
  }
})