> ## Documentation Index
> Fetch the complete documentation index at: https://docs.posthook.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Auto-Expiry (TTL)

> Automatically clean up temporary resources

Temporary resources like shareable links, export files, or beta accounts need lifecycle management. Instead of running a nightly cleanup job, you can schedule the deletion at the exact moment of creation.

## Workflow

1. **Schedule**: When you create a resource, schedule its deletion for `X` hours later.
2. **Handle**: Delete the resource.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import Posthook from '@posthook/node';
  import { Signatures, SignatureVerificationError } from '@posthook/node';

  const posthook = new Posthook(process.env.POSTHOOK_API_KEY);
  const signatures = new Signatures(process.env.POSTHOOK_SIGNING_KEY);

  /* 1. Schedule */
  async function createShareableLink(fileId) {
    // 1. Create the temporary link
    const linkToken = await db.createLink({ fileId });

    // 2. Schedule expiration for 24 hours
    await posthook.hooks.schedule({
      path: '/webhooks/expire-link',
      postIn: '24h',
      data: {
        token: linkToken
      }
    });

    return linkToken;
  }

  /* 2. Handle */
  app.post('/webhooks/expire-link', async (req, res) => {
    try {
      const delivery = signatures.parseDelivery(req.body, req.headers);

      const { token } = delivery.data;

      // Check if it was already manually deleted?
      const link = await db.getLink(token);
      if (!link) {
        return res.status(200).send('Already deleted');
      }

      // Perform the cleanup
      await db.deleteLink(token);

      res.status(200).send('Resource expired');
    } catch (err) {
      if (err instanceof SignatureVerificationError) {
        return res.status(401).json({ error: err.message });
      }
      throw err;
    }
  });
  ```

  ```python Python theme={null}
  from posthook import Posthook, SignaturesService, SignatureVerificationError
  from flask import Flask, request, jsonify
  import os

  client = Posthook(os.environ["POSTHOOK_API_KEY"])
  app = Flask(__name__)
  signatures = SignaturesService(os.environ["POSTHOOK_SIGNING_KEY"])

  # 1. Schedule
  def create_shareable_link(file_id):
      # 1. Create the temporary link
      link_token = db.create_link(file_id=file_id)

      # 2. Schedule expiration for 24 hours
      client.hooks.schedule(
          "/webhooks/expire-link",
          post_in="24h",
          data={"token": link_token}
      )

      return link_token

  # 2. Handle
  @app.route("/webhooks/expire-link", methods=["POST"])
  def handle_expire_link():
      try:
          delivery = signatures.parse_delivery(
              request.get_data(), dict(request.headers)
          )

          token = delivery.data["token"]

          # Check if it was already manually deleted?
          link = db.get_link(token)
          if not link:
              return "Already deleted", 200

          # Perform the cleanup
          db.delete_link(token)

          return "Resource expired", 200
      except SignatureVerificationError as err:
          return jsonify(error=err.message), 401
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"encoding/json"
  	"fmt"
  	"io"
  	"net/http"
  	"os"

  	posthook "github.com/posthook/posthook-go"
  )

  var client, _ = posthook.NewClient(os.Getenv("POSTHOOK_API_KEY"))
  var signatures, _ = posthook.NewSignatures(os.Getenv("POSTHOOK_SIGNING_KEY"))

  // 1. Schedule
  func createShareableLink(fileID string) string {
  	linkToken := db.CreateLink(fileID)

  	client.Hooks.Schedule(context.Background(), &posthook.HookScheduleParams{
  		Path:   "/webhooks/expire-link",
  		PostIn: "24h",
  		Data:   map[string]string{"token": linkToken},
  	})

  	return linkToken
  }

  // 2. Handle
  func handleExpireLink(w http.ResponseWriter, r *http.Request) {
  	body, _ := io.ReadAll(r.Body)

  	delivery, err := signatures.ParseDelivery(body, r.Header)
  	if err != nil {
  		http.Error(w, "Invalid signature", http.StatusUnauthorized)
  		return
  	}

  	var data struct {
  		Token string `json:"token"`
  	}
  	json.Unmarshal(delivery.Data, &data)

  	// Check if it was already manually deleted?
  	link, _ := db.GetLink(data.Token)
  	if link == nil {
  		fmt.Fprint(w, "Already deleted")
  		return
  	}

  	// Perform the cleanup
  	db.DeleteLink(data.Token)
  	fmt.Fprint(w, "Resource expired")
  }
  ```
</CodeGroup>
