5 Ways To Use Chainlink Functions in Your Decentralized Applications

Chainlink Functions is a serverless developer platform for Web3 that enables smart contracts to connect to any API and get decentralized and verifiable consensus on the result of any code you want to run. 

This is extremely powerful, because traditionally smart contracts running on a blockchain cannot easily access data and systems off-chain, and doing complex computation on-chain can be expensive. 

Below are a few sample use cases, ranging from NFT giveaways to crypto payments for music streams, that walk through how Chainlink Functions can connect decentralized applications to any API. These technical tutorials with code examples were built in collaboration with leading cloud and Web2 platforms such as Meta, Twilio, AWS, and Google Cloud to demonstrate Chainlink Functions’ extensive connectivity and showcase the new possibilities when the expansive, feature-rich world of Web2 is combined with the highly automated and secure infrastructure of Web3. 

All examples can be found on the Chainlink Labs GitHub and can be deployed today.

Meta: Connecting Social Media to Web3

Social media platforms like Instagram and Facebook serve billions of users, enabling them to stay connected with their peers and consume content. Most businesses have a heavy online presence on these platforms, with many of them driving a large majority of their business via these channels.

One use case that combines the powerful connectivity and reach of social media applications with the unique properties of the Web3 world is social media promotions and campaigns. Millions of businesses worldwide leverage the reach of social media platforms like Facebook and Instagram to share and promote new product launches via competitions, campaigns, and giveaways, with customers able to win special prizes by interacting with content shared by business pages.

In addition to this, digital collectibles were integrated into Instagram in 2022, offering creators the opportunity to share and showcase their art, images, videos, and music with their network in the form of NFTs. This provides an avenue for businesses and creators to leverage new tools to earn income, and to take more control over their work and their relationships with their fans and customers.

With Instagram’s integration of digital collectibles now being rolled out and being used by millions of people, combining digital collectibles with social media competitions and giveaways presents an incredible opportunity to showcase how social media and Web3 technologies like Chainlink Functions can be used together to empower businesses to conduct social media campaigns and competitions that leverage digital collectibles in an automated, scalable, and trust-minimized way.

The Use Case: New Product Launch NFT Giveaway

This use case example starts with a business advertising that it has a new product or service launching through its Facebook or Instagram business page, and, to celebrate the occasion, it has a limited number of unique digital collectibles in the form of NFTs to offer customers. To be eligible for one of these special NFTs, the customers need to send the business page a private message containing their wallet address and the specific hashtag for the promotion.

Business advertising a promotion via their Facebook page
Business advertising a promotion via their Facebook page
Customer participating in the promotion by sending a private message to the business
Customer participating in the promotion by sending a private message to the business

Once the timeframe for the promotion has expired, the business interacts with a smart contract to handle the NFT minting. The smart contract requires a list of eligible wallet addresses as an input, and once it receives the eligible wallet addresses, it will mint an NFT for each of them. In this example, it assumes there are three winners:

 function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal override {
    latestResponse = response;
    latestError = err;
    emit OCRResponse(requestId, response, err);

    address winner1;
    address winner2;
    address winner3;

    assembly {
      winner1 := mload(add(response, 20))
      winner2 := mload(add(response, 40))
      winner3 := mload(add(response, 60))



Flow of events for New Product Launch NFT Giveaway
Flow of events for New Product Launch NFT Giveaway

The business uses Chainlink Functions together with a smart contract to find the eligible list of customer wallet addresses. In this case, the smart contract initiates the call to Chainlink Functions, passing in the JavaScript code to be executed. This JavaScript code reaches out to the Meta Messaging API, extracts and filters out conversations that contain the relevant hashtag, and then figures out which customers should be eligible to receive an NFT (in this case, the first three that responded).

async function getEligibleConversations(isoStartDate) {
    const conversationsResponse = await Functions.makeHttpRequest({
        url: `https://graph.facebook.com/v16.0/${secrets.FACEBOOK_PAGE_ID}/conversations?fields=messages.limit(1){message,from},updated_time&access_token=${secrets.FACEBOOK_GRAPH_API_KEY}`

    if (conversationsResponse.status === 200) {
        const conversationsObject = conversationsResponse.data;
        const conversations = conversationsObject.data;

        const eligibleConversations = conversations.filter(conversation => new Date(conversation.updated_time) > isoStartDate);
        return eligibleConversations;
    } else {
        throw Error(conversationsResponse.statusText);

async function chooseWinners(eligibleConversations, numberOfWinners) {
    let winnersArray = [];
    const length = eligibleConversations.length;

    for (let i = 0; i < length;) {
        // we are getting only the latest received message from the conversation with the user
        const current = eligibleConversations[i].messages.data[0].message;

        if (current.includes("#giveaway")) {
            const walletAddress = current.substr(current.indexOf("0x"), 42);
            if (isAddress(walletAddress)) {
                    walletAddress: walletAddress,
                    senderId: eligibleConversations[i].messages.data[0].from.id
                if (winnersArray.length == numberOfWinners) {
                    return winnersArray;

    throw Error("No eligible addresses");

Once it builds up a list of wallet addresses eligible to receive an NFT, the function uses the Meta API to send a message back to each chosen user informing them that they were successful. From here, it simply returns the list of addresses to the smart contract in the form of a byte array. Once the smart contract receives the output from Chainlink Functions, it will use it to mint an NFT to each of the specified wallet addresses.


Customer receiving a notification after being chosen to receive an NFT as part of the promotion
Customer receiving a notification after being chosen to receive an NFT as part of the promotion
  async function sendNotification(recipientId) {
    await Functions.makeHttpRequest({
        method: 'POST',
        url: `https://graph.facebook.com/v16.0/${secrets.FACEBOOK_PAGE_ID}/messages?recipient={'id':'${recipientId}'}&messaging_type=MESSAGE_TAG&message={'text':'Congratulations, you were successful in winning one of our special unique NFTs to celebrate the launch of our new product! Please check your wallet address that you specified in this conversation, you should now be able to see your NFT there, or in the Instagram Digital Collectibles album if you have linked the specified wallet address to your Instagram account.'}&tag=CONFIRMED_EVENT_UPDATE&access_token=${secrets.FACEBOOK_GRAPH_API_KEY}`

async function main() {
    const isoStartDate = new Date(args[0]);
    const numberOfWinners = args[1];
    const testerAccounts = JSON.parse(args[2]);

    const eligibleConversations = await getEligibleConversations(isoStartDate);
    if (eligibleConversations === undefined || eligibleConversations.length === 0) {
        throw Error("No eligible conversations");

    // conversations are stored based on the latest update:
    // 1. the newest
    // 2. old
    // 3. the oldest
    // we want to find the fastest eligible address to award it with an NFT
    const sortedEligibleConversations = eligibleConversations.reverse();

    const chosenWinners = await chooseWinners(sortedEligibleConversations, numberOfWinners);

    const winners = chosenWinners.map(({ walletAddress }) => Buffer.from(walletAddress.slice(2), 'hex'))

    chosenWinners.forEach(async ({ senderId }) => {
        if (testerAccounts.includes(senderId)) {
            await sendNotification(senderId);

    return winners;

The final step is each customer who won the competition receiving a private message informing them that they were successful. They will be able to see their newly minted digital collectible in their Instagram Digital Collectibles gallery or in their account on OpenSea:

Viewing the NFT in Instagram Digital Collectibles once minted
Viewing the NFT in Instagram Digital Collectibles once minted
Viewing the NFT in OpenSea once minted
Viewing the NFT in OpenSea once minted

Please see the example repository for the full source code and complete instructions on how to deploy and execute this use case.

Twilio: Generating Alerts Based on On-Chain Events

Twilio is a cloud communication platform that offers a set of APIs and tools that enable developers to build and integrate messaging, voice, and video capabilities into their applications. With Twilio, developers can easily add real-time communication features to their web and mobile applications without the need for any complex infrastructure setup or maintenance.

With decentralized applications not natively able to access off-chain data and APIs, they have been limited in their functionality and ability to interact with off-chain services. With Chainlink Functions, dApp builders can now easily set up complex custom workflows that decentralize the execution of arbitrary code, run complex compute, and also consume services like Twilio’s email, WhatsApp, and SMS alerting services. This opens up a number of new features and use cases, from alerting users when a DeFi position is in danger of being liquidated to sending automated email invoices based on on-chain payments made as the result of a digital agreement.

The Use Case: Music Artist and Record Label Streaming Income Digital Agreement

This use case revolves around a digital agreement between a record label and a music artist in the form of a smart contract. The smart contract has been set up to pay out the music artist based on the number of Spotify music streams they received in the past month based on an agreed formula of X USD per Y streams. The smart contract has a function that, when invoked, executes custom logic to fetch and compare the latest streaming count to the last fetched count, calculates the payment required, and then pays out the required amount to the specified artist’s wallet address in the form of a stablecoin such as USDC. This smart contract can act as a single source of truth for the digital agreement and its state, and the data can be integrated and referenced by other systems as required.

The ability for the smart contract to reach out and find the artist’s Spotify streams and generate an email alert to the artist is not something that smart contracts can do themselves. In this example, the smart contract uses Chainlink Functions to connect to a music data API to come to consensus on the number of Spotify streams the artist has.

const URL = `https://sandbox.api.soundcharts.com/api/v2/artist/${artistId}/streaming/spotify/listeners`

const soundchartsResponse = await Functions.makeHttpRequest({
    url: URL,
    // Get a free sandbox API key from https://doc.api.soundcharts.com/api/v2/doc
    headers: { "x-app-id": secrets.soundchartAppId, "x-api-key": secrets.soundchartApiKey },

It then does the off-chain computation to calculate the payment amount, generates an email alert for the artist to inform them of the streams and payment amount using the Twilio email API, then returns the latest listener count back to the smart contract.

 const emailData = {
    personalizations: [
        to: [
            email: artistEmail,
            name: artistName,
        subject: "A payout is coming your way!",
    content: [
        type: "text/plain",
        value: `Hey ${artistName}! 
You've got ${latestListenerCount} listeners which is ${
          latestListenerCount - lastListenerCount
        } more than when we last checked!
So you can expect some cool crypto to be sent to your wallet soon!
TwiLink Records
    from: {
      email: VERIFIED_SENDER,
      name: "TwiLink Records",
    reply_to: {
      email: "[email protected]",
      name: "Sam Smith",


Twilio email notification
Twilio email notification

Once the smart contract receives the listener count, it calculates and sends the required payment of USDC to the saved artists’ wallet address, then stores the latest number of streams in the digital agreement to be used in the next month’s calculation. 

For this particular use case, having a process in place using trust-minimized smart contracts as digital agreements has multiple advantages:

  • The artist knows they will always be paid and can be sure that the record label can’t alter the conditions of the agreement.
  • The record label’s process for paying its artists is more efficient, removing the need for manual payments.
  • The solution scales well, and is automated and efficient regardless of how many artists are onboarded to the record label.

In this example, the Twilio email is being used as a simple alert for the artist. But it can also be used in conjunction with a fully designed invoice email using the Twilio SendGrid Design editor, giving the on-chain smart contract full functionality for sending professional-looking invoices to the artist, as the payments are made in real-time.

Please see the example repository for the full source code and complete instructions on how to deploy and execute this use case.

Amazon Web Services (AWS): Integrating Web3 With Cloud Systems and APIs

Cloud platforms such as Amazon Web Services (AWS) offer a wide range of cloud-based computing services to developers, including scalable and reliable infrastructure, storage solutions, database management, machine learning tools, and serverless computing. These services are used to power much of the digital world today, thanks to them being easy to integrate into developer workflows in an efficient and cost-effective way. 

Integrating these cloud services into the world of Web3 and smart contracts opens up a large number of potential use cases that fuse together the capabilities and scalability of Web2 cloud computing with the high security and trust-minimization properties of Web3 decentralized applications. 

The Use Case: A Universal Connector to Consume AWS Data APIs

This use case involves creating a universal connector Chainlink Function that can be used to connect to any AWS Data Exchange data, allowing developers to seamlessly integrate third-party data in AWS together with smart contracts. This enables the creation of advanced Web3 applications that can make use of the vast array of data sets available in AWS.

In this specific example, the universal connector will be used to connect and obtain currency exchange data from the Rearc Currency Exchange API, then return the data to an on-chain smart contract.

The Rearc currency exchange API in AWS
The Rearc currency exchange API in AWS

The universal connector has been built as a JavaScript function for all nodes in the Chainlink Functions decentralized oracle network (DON) to execute before coming to consensus on the result of the API call.

The HTTP request that Functions executes is built up programmatically, taking in a number of encoded environment variables, such as the data set ID, revision ID, and asset ID from the Rearc data set.

The authorization header is built up using the AWS access key and secret key as well as a signature. The signature is generated in the request header containing a concatenated string of the request that is then hashed with the SHA-256 hashing algorithm. For more information on generating signatures for the authorization header, see the Amazon Simple Storage Service API Reference.

const signature = buildSignature(method, url, host, secrets.secretKey, secrets.securityToken, date, payload, region, service)

const config = {
  url: `https://${host}${url}`,
  headers: {
    'x-amzn-dataexchange-data-set-id': secrets.dataSetID,
    'x-amzn-dataexchange-revision-id': secrets.revisionID,
    'x-amzn-dataexchange-asset-id': secrets.assetID,
    'X-Amz-Date': date,
    'Authorization': `AWS4-HMAC-SHA256 Credential=${secrets.accessKey}/${shortDate(date)}/${region}/${service}/aws4_request, SignedHeaders=${buildSignedHeaders(secrets.securityToken)}, Signature=${signature}`

const response = await Functions.makeHttpRequest(config)

To calculate the signature, the AWS secret key is used to derive a signing key. The derived signing key is specific to the date, service, and region. The final signature is the HMAC-SHA256 hash of the string to sign (concatenated string of the request), using the derived signing key as the key.

   * To calculate a signature, a special string has to be signed. Canonical request is part of that string. This functions takes various request parts and returns special shaped string that will be hashed later on. Since queries are passed separately we need to remove them from url parameter (if there is any)
   * @param {string} method - request method
   * @param {string} url - absolute url of the request WITHOUT query parameters
   * @param {string} host - host of the request url
   * @param {string} securityToken - optional security token when temporary credentials are used
   * @param {string} queries - encoded and sorted query parameters
   * @param {string} date - current date (ISO 8601)
   * @param {string} payload - request body for POST/PUT request, empty string for GET requests
   * @returns canonical request string
  const buildCanonicalRequest = (method, url, host, securityToken, queries, date, payload) => {
    url = url.split('?')[0]
    return method + '\n'
      + encodeURI(url) + '\n'
      + queries + '\n'
      + 'host:' + host + '\n'
      + 'x-amz-date:' + date + '\n'
      + (securityToken ? 'x-amz-security-token:' + securityToken + '\n' : '')
      + '\n'
      + buildSignedHeaders(securityToken) + '\n'
      + crypto.createHash('sha256').update(payload).digest('hex')

Once each node in the Chainlink Functions DON has executed the AWS API call and the DON has come to consensus on the result, it is then encoded as a uint256 and posted back to the consuming smart contract. The complete source code for this example can be found in the AWS Data Exchange GitHub repository.

This example demonstrates just one of many ways of integrating smart contracts with AWS. Developers can easily modify the universal connector to accommodate some of the other capabilities of AWS that can be accessed via APIs, such as querying and updating data on an Amazon Relational Database Service (RDS) or enabling a smart contract to execute a Lambda Function hosted on AWS. 

Google: Integrating Decentralized Applications With BigQuery and Analytics

Google Analytics is a popular web analytics service that allows website owners to track and analyze traffic and user behavior. While it was designed to be used with traditional websites, it can also be used with decentralized applications (dApps) and smart contracts.

Google BigQuery is a cloud-native data warehouse that enables businesses to analyze and query large datasets in real-time. 

One particular example of integrating Google Analytics and BigQuery with smart contracts is to use Chainlink Functions and Chainlink Automation to provide live updates on-chain about website or dApp user statistics. This demo was created in collaboration with Google’s Web3 Developer Advocate Allen Day.

The Use Case: Using Analytics Data To Trigger On-Chain Logic

This use case showcases how a developer can use website data collected by Google Analytics to drive and influence logic in an on-chain smart contract. For this particular example, a user is directed to a website where they can vote for a dog or cat, with their selection being sent to Google Analytics. The collected data is then automatically uploaded to a dataset in Google Cloud’s BigQuery. From here, Chainlink Automation will be used to regularly call a Chainlink Function to pull the vote totals from Google BigQuery and then return them on-chain. The smart contract will use this analytics data to keep track of vote totals. Once the voting period has ended, a function in the smart contract will determine who the winner is.

Before a request to the Google BigQuery API can be made, Chainlink Functions must request an access token:

const jwtClaimSetObj = {
    "iss": iss,
    "scope": "https://www.googleapis.com/auth/cloud-platform.read-only",
    "aud": "https://oauth2.googleapis.com/token",
    "exp": currentTimeInSeconds + 3500,
    "iat": currentTimeInSeconds

  const jwtBase64ClaimSet = Buffer.from(JSON.stringify(jwtClaimSetObj)).toString('base64')

  const stringToSign = `${jwtBase64Headers}.${jwtBase64ClaimSet}`

  const jwtBase64Signature = crypto.sign('RSA-SHA256', stringToSign, privateKey).toString('base64')

  const jwtRequest = {
    grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
    assertion: `${jwtBase64Headers}.${jwtBase64ClaimSet}.${jwtBase64Signature}`

  const jwtRequestString = querystring.stringify(jwtRequest)

  const tokenResponse = await Functions.makeHttpRequest({
    url: 'https://oauth2.googleapis.com/token',
    method: 'post',
    data: jwtRequestString

Once this token has been obtained, it can be used in the built-up request to obtain the data from Google BigQuery for each selection:

const getSQLQuery = (propertyId) => {
  return `SELECT COUNT(DISTINCT user_pseudo_id) AS votes FROM \`${secrets.projectId}.analytics_${propertyId}.events_intraday_*\` WHERE event_name = 'page_view' OR event_name = 'user_engagement'`

const requestConfig = {
  method: 'post',
  url: `https://bigquery.googleapis.com/bigquery/v2/projects/${secrets.projectId}/queries`,
  headers: {
    "Authorization": `Bearer ${await getOauthToken(secrets.iss, secrets.key)}`,
    "Accept": 'application/json',
    "Content-Type": 'application/json'
  data: {
    "query": getSQLQuery(secrets.property1),
    "useLegacySql": false

const request1 = Functions.makeHttpRequest(requestConfig)

requestConfig.data.query = getSQLQuery(secrets.property2)
const request2 = Functions.makeHttpRequest(requestConfig)

const responses = await Promise.all([ request1, request2 ])

The returned results are then combined and sent back on-chain to the consuming smart contract:

let item1Votes
try {
  item1Votes = parseInt(responses[0].data.rows[0].f[0].v)
} catch {
  item1Votes = 0

let item2Votes
try {
  item2Votes = parseInt(responses[1].data.rows[0].f[0].v)
} catch {
  item2Votes = 0

console.log(`Item 1 votes: ${item1Votes}\nItem 2 votes: ${item2Votes}`)

return Buffer.concat([ Functions.encodeUint256(item1Votes), Functions.encodeUint256(item2Votes) ])

Once the voting period is complete, the declareWinner function will determine which of the two animals is the winner:

function declareWinner() public onlyOwner {
    if (charity1Votes == charity2Votes) {
      winner = 'Charity #1 and #2 tied!';

    if (charity1Votes > charity2Votes) {
      winner = 'Charity #1 won!';

    if (charity1Votes > charity2Votes) {
      winner = 'Charity #2 won!';

    emit WinnerDeclared(winner);

The complete source code for this example can be found in the Google BigQuery Demo GitHub repository. This simple example is limited to specific analytics data based upon two events, but acts as a vehicle for demonstrating the possibilities that can be explored when you combine decentralized applications with services like Google Analytics and Google BigQuery.

Decentralized Insurance: Leveraging Off-Chain Weather Data for Parametric Insurance 

Decentralized insurance involves using blockchain technology and smart contracts to replace traditional insurance agreements, offering a superior insurance product for both insurance companies and their clients thanks to data-driven automation, highly secure, tamper-proof digital agreements in the form of smart contracts, and instant and automated claims processing.

The biggest issue for bringing the world of parametric insurance to Web3 is the availability of high-quality, verifiable data. With Chainlink Functions, developers can easily create their own off-chain data feed by accessing and aggregating data from multiple sources and then have Chainlink Functions reach consensus on what the result of the off-chain data aggregation is before reporting the final result on-chain.

The Use Case: Parametric Insurance Contract Using Multiple Data Sources

This use case showcases how a developer can pull weather data from three different data sources, aggregate the three results off-chain, then have each node in the Chainlink Functions DON reach a consensus on the median value returned by each node before posting it on-chain.

This data will be used to determine if an insurance contract should be paid out to a client. The insurance contract ParametricInsurance will check to see what the temperature is in a given city (in this case, New York). If the temperature falls below 60 degrees Fahrenheit for three consecutive days, the contract will payout the agreed value to the client. The ParametricInsurance contract defines the terms of the agreement, such as agreed value, and the parametric parameters for the paying out of the contract:

function fulfillRequest(
        bytes32 requestId,
        bytes memory response,
        bytes memory err
    ) internal override {
      latestResponse = response;
      latestError = err;
      emit OCRResponse(requestId, response, err);
      // once callback happens, mark the timestamp
      currentTempDateChecked = block.timestamp;
      currentTemperature = uint256(bytes32(response));

      // if current temperature is under temperature which considered as cold, number of cold days increment
      if (currentTemperature > coldTemp) {
          consecutiveColdDays = 0;
      } else {
          consecutiveColdDays += 1;

      // pay the client and shut down the contract
      if(consecutiveColdDays >= COLD_DAYS_THRESHOLD) {

The Parametric-insurance-example.js Chainlink Function performs API calls to three different weather data sources, aggregates the result, then come to consensus on the median result of each node before passing the weather data back to the ParametricInsurance smart contract.

const openWeatherRequest = Functions.makeHttpRequest({
  url: `http://api.openweathermap.org/data/2.5/weather?lat=${cityLat}&lon=${cityLon}&appid=${secrets.openWeatherApiKey}&units=imperial`,

const worldWeatherRequest = Functions.makeHttpRequest({
  url: `http://api.worldweatheronline.com/premium/v1/weather.ashx?key=${secrets.worldWeatherApiKey}&q=${cityName}&format=json`,

const ambeeDataRequest = Functions.makeHttpRequest({
  url: `http://api.ambeedata.com/weather/latest/by-lat-lng?lat=${cityLat}&lng=${cityLon}`,
  headers: { "x-api-key": `${secrets.ambeeWeatherApiKey}` }

// wait data returned by multiple APIs
const [openWeatherResponse, worldWeatherResponse, ambeeDataResponse] = await Promise.all([

The complete source code for this example can be found in the Parametric Insurance GitHub repository. This example is specific to parametric insurance, but the idea showcases how easy it is to consume data from multiple sources, perform off-chain computation such as aggregation on it, and then use Chainlink Functions’ OCR consensus protocol to further verify the result of the computation before delivering it on-chain.


From social media to cloud computing and insurance protocols, Chainlink Functions opens up a plethora of smart contract use cases by enabling developers to easily and securely access off-chain data and computation in a highly secure and trust-minimized way. 

To see more use cases, or to submit your own, we encourage you to visit ​​Use Chainlink Functions, a website that displays community-submitted Chainlink Functions use cases and examples. 

Bringing all the world’s data and APIs to decentralized applications will unleash an explosion of new use cases, similar to how Chainlink Price Feeds was the catalyst for the growth of DeFi. But the difference with Chainlink Functions is that Chainlink isn’t just a price data oracle—it becomes an any data oracle—enabling developers to access any data on-chain and unlocking exciting use cases across the entire Web3 space.

Need Integration Support?
Talk to an expert
Get testnet tokens
Read the Docs
Technical documentation