Keyframe on text body in Python? I'm trying to animate a paragraph of text where each word is a separate frame. Looping through the full text can come later, right now I'm just trying to figure out switching the text from one frame to another. I don't want or need to animate typing and deleting text, I just want every frame to have a different text body. Here's what I have:

import bpy

text = bpy.data.objects['Text']
text.data.body = 'Here is my text'
text.keyframe_insert(data_path="data.body", frame=1)

text.data.body = 'Now it should change'
text.keyframe_insert(data_path="data.body", frame=2)


The error I get on the first keyframe_insert line is ValueError: bpy_struct.keyframe_insert() path spans ID blocks. Is it even possible to keyframe the body? I don't actually know what data_path I should be aiming for, data.body was just a guess. I haven't found a ton of resources on animating object properties, or even what object properties are legal to animate, so any answers or resources in that direction would be much appreciated.
I don't think you can keyframe the body of a text object, directly, so I think you should do something like this:

import bpy

def update(self):
    text = bpy.data.objects['Text']
    frame = bpy.context.scene.frame_current
    if frame &lt;= 1:
        text.data.body = 'Here is my text'
    elif frame &gt;= 2:
        text.data.body = 'Now it should change'

def register():
    bpy.app.handlers.frame_change_post.append(update)

def unregister():
    bpy.app.handlers.frame_change_post.remove(update)

register()


I have formatted this to be ready to be placed in an addon (you can see the register functions there), but you can use it as you want.

The idea is to have a frame_change handler that triggers an update function every time you change the frame (it's ideal for animations). The update function simply changes the text.data.body based on the current frame.

If you want to have more flexibility when animating, you can use custom properties:

import bpy

bpy.data.objects['Text']["Text animator"] = 0       #create custom prop

def update(self):
    text = bpy.data.objects['Text']
    frame = bpy.context.scene.frame_current
    if text ["Text animator"] &lt; 1:
        text.data.body = 'Here is my text'
    elif text ["Text animator"] &gt;= 1:
        text.data.body = 'Now it should change'

def register():
    bpy.app.handlers.frame_change_post.append(update)

def unregister():
    bpy.app.handlers.frame_change_post.remove(update)

register()


This way you can easily animate the custom property using keyframes and fcurves, and when the property value is more or less than 1 it changes the text body (of course you can set up more elif statements for values greater than 2, 3, 4, etc)